diff options
author | Pavel Labath <pavel@labath.sk> | 2020-03-24 17:49:55 +0100 |
---|---|---|
committer | Pavel Labath <pavel@labath.sk> | 2020-04-06 14:14:11 +0200 |
commit | 9154a6398eda31bfbfac3291250a2968629ebc78 (patch) | |
tree | 300a21f93c00a88d01b194e9e6711ac150a0e7ef /llvm/lib/Support/DataExtractor.cpp | |
parent | a16fffa3f6add51fe1c6ee975ace56aa06a3bea7 (diff) | |
download | llvm-9154a6398eda31bfbfac3291250a2968629ebc78.zip llvm-9154a6398eda31bfbfac3291250a2968629ebc78.tar.gz llvm-9154a6398eda31bfbfac3291250a2968629ebc78.tar.bz2 |
[llvm/Support] Make more DataExtractor methods error-aware
Summary:
This patch adds the optional Error argument, and the Cursor variants to
more DataExtractor methods. The functions now behave the same way as
other error-aware functions (they set the error when they fail, and
don't do anything if the error is already set).
I have merged the LEB128 implementations via a template (similarly to
how fixed-size functions are handled) to reduce code duplication.
Depends on D77304.
Reviewers: dblaikie, aprantl
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77306
Diffstat (limited to 'llvm/lib/Support/DataExtractor.cpp')
-rw-r--r-- | llvm/lib/Support/DataExtractor.cpp | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp index 764c3fa..aaf20eb 100644 --- a/llvm/lib/Support/DataExtractor.cpp +++ b/llvm/lib/Support/DataExtractor.cpp @@ -95,9 +95,9 @@ uint16_t *DataExtractor::getU16(uint64_t *offset_ptr, uint16_t *dst, Data.data(), nullptr); } -uint32_t DataExtractor::getU24(uint64_t *offset_ptr) const { +uint32_t DataExtractor::getU24(uint64_t *OffsetPtr, Error *Err) const { uint24_t ExtractedVal = - getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data(), nullptr); + getU<uint24_t>(OffsetPtr, this, IsLittleEndian, Data.data(), Err); // The 3 bytes are in the correct byte order for the host. return ExtractedVal.getAsUint32(sys::IsLittleEndianHost); } @@ -174,47 +174,51 @@ StringRef DataExtractor::getFixedLengthString(uint64_t *OffsetPtr, return Bytes.trim(TrimChars); } -StringRef DataExtractor::getBytes(uint64_t *OffsetPtr, uint64_t Length) const { - if (!isValidOffsetForDataOfSize(*OffsetPtr, Length)) +StringRef DataExtractor::getBytes(uint64_t *OffsetPtr, uint64_t Length, + Error *Err) const { + ErrorAsOutParameter ErrAsOut(Err); + if (isError(Err)) + return StringRef(); + + if (!isValidOffsetForDataOfSize(*OffsetPtr, Length)) { + unexpectedEndReached(Err, *OffsetPtr); return StringRef(); + } + StringRef Result = Data.substr(*OffsetPtr, Length); *OffsetPtr += Length; return Result; } -uint64_t DataExtractor::getULEB128(uint64_t *offset_ptr, - llvm::Error *Err) const { - assert(*offset_ptr <= Data.size()); +template <typename T> +static T getLEB128(StringRef Data, uint64_t *OffsetPtr, Error *Err, + T (&Decoder)(const uint8_t *p, unsigned *n, + const uint8_t *end, const char **error)) { + ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(Data); + assert(*OffsetPtr <= Bytes.size()); ErrorAsOutParameter ErrAsOut(Err); if (isError(Err)) - return 0; + return T(); const char *error; unsigned bytes_read; - uint64_t result = decodeULEB128( - reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read, - reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error); + T result = + Decoder(Bytes.data() + *OffsetPtr, &bytes_read, Bytes.end(), &error); if (error) { if (Err) *Err = createStringError(errc::illegal_byte_sequence, error); - return 0; + return T(); } - *offset_ptr += bytes_read; + *OffsetPtr += bytes_read; return result; } -int64_t DataExtractor::getSLEB128(uint64_t *offset_ptr) const { - assert(*offset_ptr <= Data.size()); +uint64_t DataExtractor::getULEB128(uint64_t *offset_ptr, Error *Err) const { + return getLEB128(Data, offset_ptr, Err, decodeULEB128); +} - const char *error; - unsigned bytes_read; - int64_t result = decodeSLEB128( - reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read, - reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error); - if (error) - return 0; - *offset_ptr += bytes_read; - return result; +int64_t DataExtractor::getSLEB128(uint64_t *offset_ptr, Error *Err) const { + return getLEB128(Data, offset_ptr, Err, decodeSLEB128); } void DataExtractor::skip(Cursor &C, uint64_t Length) const { |