Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h @@ -35,12 +35,12 @@ /// Extracts a value and applies a relocation to the result if /// one exists for the given offset. - uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off, + uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex = nullptr) const; /// Extracts an address-sized value and applies a relocation to the result if /// one exists for the given offset. - uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const { + uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const { return getRelocatedValue(getAddressSize(), Off, SecIx); } @@ -48,10 +48,23 @@ /// There is a DWARF encoding that uses a PC-relative adjustment. /// For these values, \p AbsPosOffset is used to fix them, which should /// reflect the absolute address of this pointer. - Optional getEncodedPointer(uint32_t *Offset, uint8_t Encoding, + Optional getEncodedPointer(uint64_t *Offset, uint8_t Encoding, uint64_t AbsPosOffset = 0) const; size_t size() const { return Section == nullptr ? 0 : Section->Data.size(); } + + // The following methods are temporarily kept in order to preserve + // compatibility with existing code and migrate to 64-bit offsets smoothly. + // They will be removed when the migration is finished. + // Please do not use them in new code. + uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off, + uint64_t *SectionIndex = nullptr) const; + uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const { + return getRelocatedValue(getAddressSize(), Off, SecIx); + } + Optional getEncodedPointer(uint32_t *Offset, uint8_t Encoding, + uint64_t AbsPosOffset = 0) const; + }; } // end namespace llvm Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -70,7 +70,7 @@ static DWARFFormValue createFromBlockValue(dwarf::Form F, ArrayRef D); static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, - uint32_t *OffsetPtr); + uint64_t *OffsetPtr); dwarf::Form getForm() const { return Form; } uint64_t getRawUValue() const { return Value.uval; } @@ -87,12 +87,12 @@ /// in \p FormParams is needed to interpret some forms. The optional /// \p Context and \p Unit allows extracting information if the form refers /// to other sections (e.g., .debug_str). - bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, + bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context = nullptr, const DWARFUnit *Unit = nullptr); - bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, + bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFUnit *U) { return extractValue(Data, OffsetPtr, FormParams, nullptr, U); } @@ -128,7 +128,7 @@ /// \param OffsetPtr A reference to the offset that will be updated. /// \param Params DWARF parameters to help interpret forms. /// \returns true on success, false if the form was not skipped. - bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, + bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const { return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); } @@ -144,6 +144,28 @@ /// \param FormParams DWARF parameters to help interpret forms. /// \returns true on success, false if the form was not skipped. static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, + uint64_t *OffsetPtr, + const dwarf::FormParams FormParams); + + // The following methods are temporarily kept in order to preserve + // compatibility with existing code and migrate to 64-bit offsets smoothly. + // They will be removed when the migration is finished. + // Please do not use them in new code. + static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, + uint32_t *OffsetPtr); + bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, + dwarf::FormParams FormParams, + const DWARFContext *Context = nullptr, + const DWARFUnit *Unit = nullptr); + bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, + dwarf::FormParams FormParams, const DWARFUnit *U) { + return extractValue(Data, OffsetPtr, FormParams, nullptr, U); + } + bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, + const dwarf::FormParams Params) const { + return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); + } + static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, uint32_t *OffsetPtr, const dwarf::FormParams FormParams); Index: llvm/trunk/include/llvm/Support/DataExtractor.h =================================================================== --- llvm/trunk/include/llvm/Support/DataExtractor.h +++ llvm/trunk/include/llvm/Support/DataExtractor.h @@ -79,17 +79,17 @@ /// pointed to by \a offset_ptr is out of bounds, or if the /// offset plus the length of the C string is out of bounds, /// NULL will be returned. - const char *getCStr(uint32_t *offset_ptr) const; + const char *getCStr(uint64_t *offset_ptr) const; - /// Extract a C string from \a *OffsetPtr. + /// Extract a C string from \a *offset_ptr. /// /// Returns a StringRef for the C String from the data at the offset - /// pointed to by \a OffsetPtr. A variable length NULL terminated C - /// string will be extracted and the \a OffsetPtr will be + /// pointed to by \a offset_ptr. A variable length NULL terminated C + /// string will be extracted and the \a offset_ptr will be /// updated with the offset of the byte that follows the NULL /// terminator byte. /// - /// \param[in,out] OffsetPtr + /// \param[in,out] offset_ptr /// A pointer to an offset within the data that will be advanced /// by the appropriate number of bytes if the value is extracted /// correctly. If the offset is out of bounds or there are not @@ -98,10 +98,10 @@ /// /// \return /// A StringRef for the C string value in the data. If the offset - /// pointed to by \a OffsetPtr is out of bounds, or if the + /// pointed to by \a offset_ptr is out of bounds, or if the /// offset plus the length of the C string is out of bounds, /// a default-initialized StringRef will be returned. - StringRef getCStrRef(uint32_t *OffsetPtr) const; + StringRef getCStrRef(uint64_t *offset_ptr) const; /// Extract an unsigned integer of size \a byte_size from \a /// *offset_ptr. @@ -127,7 +127,7 @@ /// @return /// The unsigned integer value that was extracted, or zero on /// failure. - uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const; + uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size) const; /// Extract an signed integer of size \a byte_size from \a *offset_ptr. /// @@ -152,7 +152,7 @@ /// @return /// The sign extended signed integer value that was extracted, /// or zero on failure. - int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; + int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const; //------------------------------------------------------------------ /// Extract an pointer from \a *offset_ptr. @@ -171,7 +171,7 @@ /// /// @return /// The extracted pointer value as a 64 integer. - uint64_t getAddress(uint32_t *offset_ptr) const { + uint64_t getAddress(uint64_t *offset_ptr) const { return getUnsigned(offset_ptr, AddressSize); } @@ -189,7 +189,7 @@ /// /// @return /// The extracted uint8_t value. - uint8_t getU8(uint32_t *offset_ptr) const; + uint8_t getU8(uint64_t *offset_ptr) const; /// Extract \a count uint8_t values from \a *offset_ptr. /// @@ -214,7 +214,7 @@ /// @return /// \a dst if all values were properly extracted and copied, /// NULL otherise. - uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const; + uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const; //------------------------------------------------------------------ /// Extract a uint16_t value from \a *offset_ptr. @@ -232,7 +232,7 @@ /// @return /// The extracted uint16_t value. //------------------------------------------------------------------ - uint16_t getU16(uint32_t *offset_ptr) const; + uint16_t getU16(uint64_t *offset_ptr) const; /// Extract \a count uint16_t values from \a *offset_ptr. /// @@ -257,7 +257,7 @@ /// @return /// \a dst if all values were properly extracted and copied, /// NULL otherise. - uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const; + uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst, uint32_t count) const; /// Extract a 24-bit unsigned value from \a *offset_ptr and return it /// in a uint32_t. @@ -274,7 +274,7 @@ /// /// @return /// The extracted 24-bit value represented in a uint32_t. - uint32_t getU24(uint32_t *offset_ptr) const; + uint32_t getU24(uint64_t *offset_ptr) const; /// Extract a uint32_t value from \a *offset_ptr. /// @@ -290,7 +290,7 @@ /// /// @return /// The extracted uint32_t value. - uint32_t getU32(uint32_t *offset_ptr) const; + uint32_t getU32(uint64_t *offset_ptr) const; /// Extract \a count uint32_t values from \a *offset_ptr. /// @@ -315,7 +315,7 @@ /// @return /// \a dst if all values were properly extracted and copied, /// NULL otherise. - uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const; + uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst, uint32_t count) const; /// Extract a uint64_t value from \a *offset_ptr. /// @@ -331,7 +331,7 @@ /// /// @return /// The extracted uint64_t value. - uint64_t getU64(uint32_t *offset_ptr) const; + uint64_t getU64(uint64_t *offset_ptr) const; /// Extract \a count uint64_t values from \a *offset_ptr. /// @@ -356,7 +356,7 @@ /// @return /// \a dst if all values were properly extracted and copied, /// NULL otherise. - uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const; + uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst, uint32_t count) const; /// Extract a signed LEB128 value from \a *offset_ptr. /// @@ -374,7 +374,7 @@ /// /// @return /// The extracted signed integer value. - int64_t getSLEB128(uint32_t *offset_ptr) const; + int64_t getSLEB128(uint64_t *offset_ptr) const; /// Extract a unsigned LEB128 value from \a *offset_ptr. /// @@ -392,21 +392,21 @@ /// /// @return /// The extracted unsigned integer value. - uint64_t getULEB128(uint32_t *offset_ptr) const; + uint64_t getULEB128(uint64_t *offset_ptr) const; /// Test the validity of \a offset. /// /// @return /// \b true if \a offset is a valid offset into the data in this /// object, \b false otherwise. - bool isValidOffset(uint32_t offset) const { return Data.size() > offset; } + bool isValidOffset(uint64_t offset) const { return Data.size() > offset; } /// Test the availability of \a length bytes of data from \a offset. /// /// @return /// \b true if \a offset is a valid offset and there are \a /// length bytes available at that offset, \b false otherwise. - bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const { + bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const { return offset + length >= offset && isValidOffset(offset + length - 1); } @@ -417,9 +417,32 @@ /// \b true if \a offset is a valid offset and there are enough /// bytes for a pointer available at that offset, \b false /// otherwise. - bool isValidOffsetForAddress(uint32_t offset) const { + bool isValidOffsetForAddress(uint64_t offset) const { return isValidOffsetForDataOfSize(offset, AddressSize); } + + // The following methods are temporarily kept in order to preserve + // compatibility with existing code and migrate to 64-bit offsets smoothly. + // They will be removed when the migration is finished. + // Please do not use them in new code. + const char *getCStr(uint32_t *offset_ptr) const; + StringRef getCStrRef(uint32_t *offset_ptr) const; + uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const; + int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; + uint64_t getAddress(uint32_t *offset_ptr) const { + return getUnsigned(offset_ptr, AddressSize); + } + uint8_t getU8(uint32_t *offset_ptr) const; + uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const; + uint16_t getU16(uint32_t *offset_ptr) const; + uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const; + uint32_t getU24(uint32_t *offset_ptr) const; + uint32_t getU32(uint32_t *offset_ptr) const; + uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const; + uint64_t getU64(uint32_t *offset_ptr) const; + uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const; + int64_t getSLEB128(uint32_t *offset_ptr) const; + uint64_t getULEB128(uint32_t *offset_ptr) const; }; } // namespace llvm Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -12,7 +12,7 @@ using namespace llvm; -uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, +uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SecNdx) const { if (SecNdx) *SecNdx = object::SectionedAddress::UndefSection; @@ -31,13 +31,13 @@ } Optional -DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, +DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, uint64_t PCRelOffset) const { if (Encoding == dwarf::DW_EH_PE_omit) return None; uint64_t Result = 0; - uint32_t OldOffset = *Offset; + uint64_t OldOffset = *Offset; // First get value switch (Encoding & 0x0F) { case dwarf::DW_EH_PE_absptr: @@ -97,3 +97,33 @@ 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; + +public: + WrapOffset(uint32_t *Offset) + : Offset64(*Offset), Offset32(Offset) {} + ~WrapOffset() { *Offset32 = Offset64; } + operator uint64_t *() { return &Offset64; } +}; + +} + +uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, + uint64_t *SecNdx) const { + return getRelocatedValue(Size, WrapOffset(Off), SecNdx); +} + +Optional +DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, + uint64_t PCRelOffset) const { + return getEncodedPointer(WrapOffset(Offset), Encoding, PCRelOffset); +} Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -98,7 +98,7 @@ } DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { DWARFFormValue FormValue(F); FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U->getFormParams(), U); @@ -106,7 +106,7 @@ } bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, + uint64_t *OffsetPtr, const dwarf::FormParams Params) { bool Indirect = false; do { @@ -234,7 +234,7 @@ } bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, - uint32_t *OffsetPtr, dwarf::FormParams FP, + uint64_t *OffsetPtr, dwarf::FormParams FP, const DWARFContext *Ctx, const DWARFUnit *CU) { if (!Ctx && CU) @@ -590,7 +590,7 @@ // FIXME: Add support for DW_FORM_GNU_strp_alt if (Form == DW_FORM_GNU_strp_alt || C == nullptr) return None; - uint32_t Offset = Value.uval; + uint64_t Offset = Value.uval; if (Form == DW_FORM_line_strp) { // .debug_line_str is tracked in the Context. if (const char *Str = C->getLineStringExtractor().getCStr(&Offset)) @@ -624,6 +624,7 @@ return SA->Address; return None; } + Optional DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) @@ -717,3 +718,40 @@ return None; return Value.uval; } + +// 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; + +public: + WrapOffset(uint32_t *Offset) + : Offset64(*Offset), Offset32(Offset) {} + ~WrapOffset() { *Offset32 = Offset64; } + operator uint64_t *() { return &Offset64; } +}; + +} + +DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, + uint32_t *OffsetPtr) { + return createFromUnit(F, U, WrapOffset(OffsetPtr)); +} + +bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, + uint32_t *OffsetPtr, + const dwarf::FormParams Params) { + return skipValue(Form, DebugInfoData, WrapOffset(OffsetPtr), Params); +} + +bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, + uint32_t *OffsetPtr, dwarf::FormParams FP, + const DWARFContext *Ctx, + const DWARFUnit *CU) { + return extractValue(Data, WrapOffset(OffsetPtr), FP, Ctx, CU); +} Index: llvm/trunk/lib/Support/DataExtractor.cpp =================================================================== --- llvm/trunk/lib/Support/DataExtractor.cpp +++ llvm/trunk/lib/Support/DataExtractor.cpp @@ -14,10 +14,10 @@ using namespace llvm; template -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 @@ } template -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 @@ return nullptr; } -uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const { +uint8_t DataExtractor::getU8(uint64_t *offset_ptr) const { return getU(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(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(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(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(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(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(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(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(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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ *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)); +} Index: llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp =================================================================== --- llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp +++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp @@ -41,7 +41,7 @@ DWARFFormValue createDataXFormValue(dwarf::Form Form, RawTypeT Value) { char Raw[sizeof(RawTypeT)]; memcpy(Raw, &Value, sizeof(RawTypeT)); - uint32_t Offset = 0; + uint64_t Offset = 0; DWARFFormValue Result(Form); DWARFDataExtractor Data(StringRef(Raw, sizeof(RawTypeT)), sys::IsLittleEndianHost, sizeof(void *)); @@ -53,7 +53,7 @@ SmallString<10> RawData; raw_svector_ostream OS(RawData); encodeULEB128(Value, OS); - uint32_t Offset = 0; + uint64_t Offset = 0; DWARFFormValue Result(DW_FORM_udata); DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *)); Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); @@ -64,7 +64,7 @@ SmallString<10> RawData; raw_svector_ostream OS(RawData); encodeSLEB128(Value, OS); - uint32_t Offset = 0; + uint64_t Offset = 0; DWARFFormValue Result(DW_FORM_sdata); DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *)); Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); @@ -112,7 +112,7 @@ DWARFFormValue Data16(DW_FORM_data16); DWARFDataExtractor DE16(StringRef(Cksum, 16), sys::IsLittleEndianHost, sizeof(void *)); - uint32_t Offset = 0; + uint64_t Offset = 0; Data16.extractValue(DE16, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); SmallString<32> Str; raw_svector_ostream Res(Str); Index: llvm/trunk/unittests/Support/DataExtractorTest.cpp =================================================================== --- llvm/trunk/unittests/Support/DataExtractorTest.cpp +++ llvm/trunk/unittests/Support/DataExtractorTest.cpp @@ -12,19 +12,27 @@ namespace { +// Test fixture +template +class DataExtractorTest : public ::testing::Test { }; + +// Test DataExtractor with both types which can be used for offsets. +typedef ::testing::Types TestTypes; +TYPED_TEST_CASE(DataExtractorTest, TestTypes); + const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00"; const char stringData[] = "hellohello\0hello"; const char leb128data[] = "\xA6\x49"; const char bigleb128data[] = "\xAA\xA9\xFF\xAA\xFF\xAA\xFF\x4A"; -TEST(DataExtractorTest, OffsetOverflow) { +TYPED_TEST(DataExtractorTest, OffsetOverflow) { DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5)); } -TEST(DataExtractorTest, UnsignedNumbers) { +TYPED_TEST(DataExtractorTest, UnsignedNumbers) { DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); - uint32_t offset = 0; + TypeParam offset = 0; EXPECT_EQ(0x80U, DE.getU8(&offset)); EXPECT_EQ(1U, offset); @@ -70,9 +78,9 @@ EXPECT_EQ(8U, offset); } -TEST(DataExtractorTest, SignedNumbers) { +TYPED_TEST(DataExtractorTest, SignedNumbers) { DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); - uint32_t offset = 0; + TypeParam offset = 0; EXPECT_EQ(-128, DE.getSigned(&offset, 1)); EXPECT_EQ(1U, offset); @@ -87,9 +95,9 @@ EXPECT_EQ(8U, offset); } -TEST(DataExtractorTest, Strings) { +TYPED_TEST(DataExtractorTest, Strings) { DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8); - uint32_t offset = 0; + TypeParam offset = 0; EXPECT_EQ(stringData, DE.getCStr(&offset)); EXPECT_EQ(11U, offset); @@ -97,9 +105,9 @@ EXPECT_EQ(11U, offset); } -TEST(DataExtractorTest, LEB128) { +TYPED_TEST(DataExtractorTest, LEB128) { DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8); - uint32_t offset = 0; + TypeParam offset = 0; EXPECT_EQ(9382ULL, DE.getULEB128(&offset)); EXPECT_EQ(2U, offset); @@ -116,9 +124,9 @@ EXPECT_EQ(8U, offset); } -TEST(DataExtractorTest, LEB128_error) { +TYPED_TEST(DataExtractorTest, LEB128_error) { DataExtractor DE(StringRef("\x81"), false, 8); - uint32_t Offset = 0; + TypeParam Offset = 0; EXPECT_EQ(0U, DE.getULEB128(&Offset)); EXPECT_EQ(0U, Offset);