summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/DataExtractor.cpp
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin@accesssoftek.com>2019-08-06 10:47:20 +0000
committerIgor Kudrin <ikudrin@accesssoftek.com>2019-08-06 10:47:20 +0000
commitf5f35c5cd110e22c4b216ec1dc53255e32adc011 (patch)
treeff284ebcb776857fe4043391261ae627d08321f3 /llvm/lib/Support/DataExtractor.cpp
parent7b24dd741c6c4734f8cf5b9fafc12bf9e38411d6 (diff)
downloadbcm5719-llvm-f5f35c5cd110e22c4b216ec1dc53255e32adc011.tar.gz
bcm5719-llvm-f5f35c5cd110e22c4b216ec1dc53255e32adc011.zip
Support 64-bit offsets in utility classes (1/5)
Using 64-bit offsets is required to fully implement 64-bit DWARF. As these classes are used in many different libraries they should temporarily support both 32- and 64-bit offsets. Differential Revision: https://reviews.llvm.org/D64006 llvm-svn: 368013
Diffstat (limited to 'llvm/lib/Support/DataExtractor.cpp')
-rw-r--r--llvm/lib/Support/DataExtractor.cpp130
1 files changed, 107 insertions, 23 deletions
diff --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp
index 673bbb4d06f..73c215ea05a 100644
--- a/llvm/lib/Support/DataExtractor.cpp
+++ b/llvm/lib/Support/DataExtractor.cpp
@@ -14,10 +14,10 @@
using namespace llvm;
template <typename T>
-static T getU(uint32_t *offset_ptr, const DataExtractor *de,
+static T getU(uint64_t *offset_ptr, const DataExtractor *de,
bool isLittleEndian, const char *Data) {
T val = 0;
- uint32_t offset = *offset_ptr;
+ uint64_t offset = *offset_ptr;
if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
std::memcpy(&val, &Data[offset], sizeof(val));
if (sys::IsLittleEndianHost != isLittleEndian)
@@ -30,9 +30,9 @@ static T getU(uint32_t *offset_ptr, const DataExtractor *de,
}
template <typename T>
-static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
+static T *getUs(uint64_t *offset_ptr, T *dst, uint32_t count,
const DataExtractor *de, bool isLittleEndian, const char *Data){
- uint32_t offset = *offset_ptr;
+ uint64_t offset = *offset_ptr;
if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
@@ -47,56 +47,55 @@ static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
return nullptr;
}
-uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
+uint8_t DataExtractor::getU8(uint64_t *offset_ptr) const {
return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data());
}
uint8_t *
-DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
+DataExtractor::getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const {
return getUs<uint8_t>(offset_ptr, dst, count, this, IsLittleEndian,
Data.data());
}
-
-uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
+uint16_t DataExtractor::getU16(uint64_t *offset_ptr) const {
return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data());
}
-uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
+uint16_t *DataExtractor::getU16(uint64_t *offset_ptr, uint16_t *dst,
uint32_t count) const {
return getUs<uint16_t>(offset_ptr, dst, count, this, IsLittleEndian,
Data.data());
}
-uint32_t DataExtractor::getU24(uint32_t *offset_ptr) const {
+uint32_t DataExtractor::getU24(uint64_t *offset_ptr) const {
uint24_t ExtractedVal =
getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data());
// The 3 bytes are in the correct byte order for the host.
return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
}
-uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
+uint32_t DataExtractor::getU32(uint64_t *offset_ptr) const {
return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data());
}
-uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
+uint32_t *DataExtractor::getU32(uint64_t *offset_ptr, uint32_t *dst,
uint32_t count) const {
return getUs<uint32_t>(offset_ptr, dst, count, this, IsLittleEndian,
Data.data());
}
-uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
+uint64_t DataExtractor::getU64(uint64_t *offset_ptr) const {
return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data());
}
-uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
+uint64_t *DataExtractor::getU64(uint64_t *offset_ptr, uint64_t *dst,
uint32_t count) const {
return getUs<uint64_t>(offset_ptr, dst, count, this, IsLittleEndian,
Data.data());
}
uint64_t
-DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+DataExtractor::getUnsigned(uint64_t *offset_ptr, uint32_t byte_size) const {
switch (byte_size) {
case 1:
return getU8(offset_ptr);
@@ -111,7 +110,7 @@ DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
}
int64_t
-DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+DataExtractor::getSigned(uint64_t *offset_ptr, uint32_t byte_size) const {
switch (byte_size) {
case 1:
return (int8_t)getU8(offset_ptr);
@@ -125,8 +124,8 @@ DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
llvm_unreachable("getSigned unhandled case!");
}
-const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
- uint32_t offset = *offset_ptr;
+const char *DataExtractor::getCStr(uint64_t *offset_ptr) const {
+ uint64_t offset = *offset_ptr;
StringRef::size_type pos = Data.find('\0', offset);
if (pos != StringRef::npos) {
*offset_ptr = pos + 1;
@@ -135,17 +134,17 @@ const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
return nullptr;
}
-StringRef DataExtractor::getCStrRef(uint32_t *OffsetPtr) const {
- uint32_t Start = *OffsetPtr;
+StringRef DataExtractor::getCStrRef(uint64_t *offset_ptr) const {
+ uint64_t Start = *offset_ptr;
StringRef::size_type Pos = Data.find('\0', Start);
if (Pos != StringRef::npos) {
- *OffsetPtr = Pos + 1;
+ *offset_ptr = Pos + 1;
return StringRef(Data.data() + Start, Pos - Start);
}
return StringRef();
}
-uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
+uint64_t DataExtractor::getULEB128(uint64_t *offset_ptr) const {
assert(*offset_ptr <= Data.size());
const char *error;
@@ -159,7 +158,7 @@ uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
return result;
}
-int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
+int64_t DataExtractor::getSLEB128(uint64_t *offset_ptr) const {
assert(*offset_ptr <= Data.size());
const char *error;
@@ -172,3 +171,88 @@ int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
*offset_ptr += bytes_read;
return result;
}
+
+// The following is temporary code aimed to preserve compatibility with
+// existing code which uses 32-bit offsets.
+// It will be removed when migration to 64-bit offsets is finished.
+
+namespace {
+
+class WrapOffset {
+ uint64_t offset64;
+ uint32_t *offset32_ptr;
+
+public:
+ WrapOffset(uint32_t *offset_ptr)
+ : offset64(*offset_ptr), offset32_ptr(offset_ptr) {}
+ ~WrapOffset() { *offset32_ptr = offset64; }
+ operator uint64_t *() { return &offset64; }
+};
+
+}
+
+uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
+ return getU8(WrapOffset(offset_ptr));
+}
+
+uint8_t *
+DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
+ return getU8(WrapOffset(offset_ptr), dst, count);
+}
+
+uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
+ return getU16(WrapOffset(offset_ptr));
+}
+
+uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
+ uint32_t count) const {
+ return getU16(WrapOffset(offset_ptr), dst, count);
+}
+
+uint32_t DataExtractor::getU24(uint32_t *offset_ptr) const {
+ return getU24(WrapOffset(offset_ptr));
+}
+
+uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
+ return getU32(WrapOffset(offset_ptr));
+}
+
+uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
+ uint32_t count) const {
+ return getU32(WrapOffset(offset_ptr), dst, count);
+}
+
+uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
+ return getU64(WrapOffset(offset_ptr));
+}
+
+uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
+ uint32_t count) const {
+ return getU64(WrapOffset(offset_ptr), dst, count);
+}
+
+uint64_t
+DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ return getUnsigned(WrapOffset(offset_ptr), byte_size);
+}
+
+int64_t
+DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ return getSigned(WrapOffset(offset_ptr), byte_size);
+}
+
+const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
+ return getCStr(WrapOffset(offset_ptr));
+}
+
+StringRef DataExtractor::getCStrRef(uint32_t *offset_ptr) const {
+ return getCStrRef(WrapOffset(offset_ptr));
+}
+
+uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
+ return getULEB128(WrapOffset(offset_ptr));
+}
+
+int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
+ return getSLEB128(WrapOffset(offset_ptr));
+}
OpenPOWER on IntegriCloud