[llvm] r286597 - Clean up DWARFFormValue by reducing duplicated code and removing DWARFFormValue::getFixedFormSizes()
Greg Clayton via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 11 09:48:44 PST 2016
Thanks for the comments. Fixed with:
% svn commit
Sending lib/DebugInfo/DWARF/DWARFFormValue.cpp
Transmitting file data .done
Committing transaction...
Committed revision 286603.
Paul, do you mind if I add you to as a reviewer on future patches?
> On Nov 11, 2016, at 9:30 AM, Robinson, Paul <paul.robinson at sony.com> wrote:
>
> Now that I read the patch... several inline comments.
> --paulr
>
>> -----Original Message-----
>> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On Behalf
>> Of Greg Clayton via llvm-commits
>> Sent: Friday, November 11, 2016 8:22 AM
>> To: llvm-commits at lists.llvm.org
>> Subject: [llvm] r286597 - Clean up DWARFFormValue by reducing duplicated
>> code and removing DWARFFormValue::getFixedFormSizes()
>>
>> Author: gclayton
>> Date: Fri Nov 11 10:21:37 2016
>> New Revision: 286597
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=286597&view=rev
>> Log:
>> Clean up DWARFFormValue by reducing duplicated code and removing
>> DWARFFormValue::getFixedFormSizes()
>>
>> In preparation for a follow on patch that improves DWARF parsing speed,
>> clean up DWARFFormValue so that we have can get the fixed byte size of a
>> form value given a DWARFUnit or given the version, address byte size and
>> dwarf32/64.
>>
>> This patch cleans up code so that everyone is using one of the new
>> DWARFFormValue functions:
>>
>> static Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form
>> Form, const DWARFUnit *U = nullptr);
>> static Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form
>> Form, uint16_t Version, uint8_t AddrSize, bool Dwarf32);
>>
>> This patch changes DWARFFormValue::skipValue() to rely on the output of
>> DWARFFormValue::getFixedByteSize(...) instead of duplicating the code in
>> each function. This will reduce the number of changes we need to make to
>> DWARF to fewer places in DWARFFormValue when we add support for new form.
>>
>> This patch also starts to support DWARF64 so that we can get correct byte
>> sizes for forms that vary according the DWARF 32/64.
>>
>> To reduce the code duplication a new FormSizeHelper pure virtual class was
>> created that can be created as a FormSizeHelperDWARFUnit when you have a
>> DWARFUnit, or FormSizeHelperManual where you manually specify the DWARF
>> version, address byte size and DWARF32/DWARF64. There is now a single
>> implementation of a function that gets the fixed byte size (instead of two
>> where one took a DWARFUnit and one took the DWARF version, address byte
>> size and DWARFFormat enum) and one function to skip the form values.
>>
>> https://reviews.llvm.org/D26526
>>
>>
>>
>> Modified:
>> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
>> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
>> llvm/trunk/include/llvm/Support/Dwarf.h
>> llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
>> llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
>> llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp
>> llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h?rev=28659
>> 7&r1=286596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFFormValue.h Fri Nov 11
>> 10:21:37 2016
>> @@ -81,17 +81,79 @@ public:
>> Optional<uint64_t> getAsAddress() const;
>> Optional<uint64_t> getAsSectionOffset() const;
>> Optional<ArrayRef<uint8_t>> getAsBlock() const;
>> + /// Get the fixed byte size for a given form.
>> + ///
>> + /// If the form always has a fixed valid byte size that doesn't depend
>> on a
>> + /// DWARFUnit, then an Optional with a value will be returned. If the
>> form
>> + /// can vary in size depending on the DWARFUnit (DWARF version, address
>> byte
>> + /// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional
>> with a
>> + /// valid value is returned. If the form is always encoded using a
>> variable
>> + /// length storage format (ULEB or SLEB numbers or blocks) or the size
>> + /// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be
>> + /// returned.
>> + /// \param Form The DWARF form to get the fixed byte size for
>> + /// \param U The DWARFUnit that can be used to help determine the byte
>> size.
>> + ///
>> + /// \returns Optional<uint8_t> value with the fixed byte size or None
>> if
>> + /// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't
>> supplied
>> + /// and was needed to calculate the byte size.
>> + static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
>> + const DWARFUnit *U =
>> nullptr);
>> + /// Get the fixed byte size for a given form.
>> + ///
>> + /// If the form has a fixed byte size given a valid DWARF version and
>> address
>> + /// byte size, then an Optional with a valid value is returned. If the
>> form
>> + /// is always encoded using a variable length storage format (ULEB or
>> SLEB
>> + /// numbers or blocks) then None will be returned.
>> + ///
>> + /// \param Form DWARF form to get the fixed byte size for
>> + /// \param Version DWARF version number.
>> + /// \param AddrSize size of an address in bytes.
>> + /// \param Format enum value from llvm::dwarf::DwarfFormat.
>> + /// \returns Optional<uint8_t> value with the fixed byte size or None
>> if
>> + /// \p Form doesn't have a fixed byte size.
>> + static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, uint16_t
>> Version,
>> + uint8_t AddrSize,
>> + llvm::dwarf::DwarfFormat
>> Format);
>>
>> + /// Skip a form in \p debug_info_data at offset specified by \p
>> offset_ptr.
>> + ///
>> + /// Skips the bytes for this form in the debug info and updates the
>> offset.
>> + ///
>> + /// \param debug_info_data the .debug_info data to use to skip the
>> value.
>> + /// \param offset_ptr a reference to the offset that will be updated.
>> + /// \param U the DWARFUnit to use when skipping the form in case the
>> form
>> + /// size differs according to data in the DWARFUnit.
>> + /// \returns true on success, false if the form was not skipped.
>> bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
>> const DWARFUnit *U) const;
>> + /// Skip a form in \p debug_info_data at offset specified by \p
>> offset_ptr.
>> + ///
>> + /// Skips the bytes for this form in the debug info and updates the
>> offset.
>> + ///
>> + /// \param form the DW_FORM enumeration that indicates the form to
>> skip.
>> + /// \param debug_info_data the .debug_info data to use to skip the
>> value.
>> + /// \param offset_ptr a reference to the offset that will be updated.
>> + /// \param U the DWARFUnit to use when skipping the form in case the
>> form
>> + /// size differs according to data in the DWARFUnit.
>> + /// \returns true on success, false if the form was not skipped.
>> static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
>> - uint32_t *offset_ptr, const DWARFUnit *u);
>> + uint32_t *offset_ptr, const DWARFUnit *U);
>> + /// Skip a form in \p debug_info_data at offset specified by \p
>> offset_ptr.
>> + ///
>> + /// Skips the bytes for this form in the debug info and updates the
>> offset.
>> + ///
>> + /// \param form the DW_FORM enumeration that indicates the form to
>> skip.
>> + /// \param debug_info_data the .debug_info data to use to skip the
>> value.
>> + /// \param offset_ptr a reference to the offset that will be updated.
>> + /// \param Version DWARF version number.
>> + /// \param AddrSize size of an address in bytes.
>> + /// \param Format enum value from llvm::dwarf::DwarfFormat.
>> + /// \returns true on success, false if the form was not skipped.
>> static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
>> uint32_t *offset_ptr, uint16_t Version,
>> - uint8_t AddrSize);
>> + uint8_t AddrSize, llvm::dwarf::DwarfFormat
>> Format);
>>
>> - static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize,
>> - uint16_t Version);
>> private:
>> void dumpString(raw_ostream &OS) const;
>> };
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=286597&r1=
>> 286596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Fri Nov 11
>> 10:21:37 2016
>> @@ -191,13 +191,25 @@ public:
>> uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
>> uint32_t getLength() const { return Length; }
>> uint16_t getVersion() const { return Version; }
>> + dwarf::DwarfFormat getFormat() const {
>> + return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
>> + }
>> const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
>> return Abbrevs;
>> }
>> uint8_t getAddressByteSize() const { return AddrSize; }
>> uint8_t getRefAddrByteSize() const {
>> - // FIXME: Support DWARF64.
>> - return (Version == 2) ? AddrSize : 4;
>> + if (Version == 2)
>> + return AddrSize;
>> + return getDwarfOffsetByteSize();
>> + }
>> + uint8_t getDwarfOffsetByteSize() const {
>> + switch (getFormat()) {
>> + case dwarf::DwarfFormat::DWARF32:
>> + return 4;
>> + case dwarf::DwarfFormat::DWARF64:
>> + return 8;
>> + }
>> }
>> uint64_t getBaseAddress() const { return BaseAddr; }
>>
>>
>> Modified: llvm/trunk/include/llvm/Support/Dwarf.h
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/include/llvm/Support/Dwarf.h?rev=286597&r1=286596&r2=28
>> 6597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/include/llvm/Support/Dwarf.h (original)
>> +++ llvm/trunk/include/llvm/Support/Dwarf.h Fri Nov 11 10:21:37 2016
>> @@ -433,6 +433,9 @@ private:
>> };
>> };
>>
>> +/// Constants that define the DWARF format as 32 or 64 bit.
>> +enum DwarfFormat { DWARF32, DWARF64 };
>> +
>> } // End of namespace dwarf
>>
>> } // End of namespace llvm
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp?rev=286597&
>> r1=286596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp Fri Nov 11
>> 10:21:37 2016
>> @@ -202,18 +202,13 @@ bool DWARFDebugInfoEntryMinimal::extract
>> *OffsetPtr = Offset;
>> return false;
>> }
>> - ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
>> - U->getAddressByteSize(), U->getVersion());
>> - assert(FixedFormSizes.size() > 0);
>>
>> // Skip all data in the .debug_info for the attributes
>> for (const auto &AttrSpec : AbbrevDecl->attributes()) {
>> auto Form = AttrSpec.Form;
>>
>> - uint8_t FixedFormSize =
>> - (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
>> - if (FixedFormSize)
>> - *OffsetPtr += FixedFormSize;
>> + if (Optional<uint8_t> FixedSize =
>> DWARFFormValue::getFixedByteSize(Form, U))
>> + *OffsetPtr += *FixedSize;
>> else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
>> U)) {
>> // Restore the original offset.
>> *OffsetPtr = Offset;
>>
>> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp?rev=286597&r1=28
>> 6596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp Fri Nov 11 10:21:37
>> 2016
>> @@ -23,60 +23,6 @@ using namespace llvm;
>> using namespace dwarf;
>> using namespace syntax;
>>
>> -namespace {
>> -uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
>> - // FIXME: Support DWARF64.
>> - return (Version == 2) ? AddrSize : 4;
>> -}
>> -
>> -template <uint8_t AddrSize, uint8_t RefAddrSize>
>> -ArrayRef<uint8_t> makeFixedFormSizesArrayRef() {
>> - static const uint8_t sizes[] = {
>> - 0, // 0x00 unused
>> - AddrSize, // 0x01 DW_FORM_addr
>> - 0, // 0x02 unused
>> - 0, // 0x03 DW_FORM_block2
>> - 0, // 0x04 DW_FORM_block4
>> - 2, // 0x05 DW_FORM_data2
>> - 4, // 0x06 DW_FORM_data4
>> - 8, // 0x07 DW_FORM_data8
>> - 0, // 0x08 DW_FORM_string
>> - 0, // 0x09 DW_FORM_block
>> - 0, // 0x0a DW_FORM_block1
>> - 1, // 0x0b DW_FORM_data1
>> - 1, // 0x0c DW_FORM_flag
>> - 0, // 0x0d DW_FORM_sdata
>> - 4, // 0x0e DW_FORM_strp
>> - 0, // 0x0f DW_FORM_udata
>> - RefAddrSize, // 0x10 DW_FORM_ref_addr
>> - 1, // 0x11 DW_FORM_ref1
>> - 2, // 0x12 DW_FORM_ref2
>> - 4, // 0x13 DW_FORM_ref4
>> - 8, // 0x14 DW_FORM_ref8
>> - 0, // 0x15 DW_FORM_ref_udata
>> - 0, // 0x16 DW_FORM_indirect
>> - 4, // 0x17 DW_FORM_sec_offset
>> - 0, // 0x18 DW_FORM_exprloc
>> - 0, // 0x19 DW_FORM_flag_present
>> - };
>> - return makeArrayRef(sizes);
>> -}
>> -}
>> -
>> -ArrayRef<uint8_t> DWARFFormValue::getFixedFormSizes(uint8_t AddrSize,
>> - uint16_t Version) {
>> - uint8_t RefAddrSize = getRefAddrSize(AddrSize, Version);
>> - if (AddrSize == 4 && RefAddrSize == 4)
>> - return makeFixedFormSizesArrayRef<4, 4>();
>> - if (AddrSize == 4 && RefAddrSize == 8)
>> - return makeFixedFormSizesArrayRef<4, 8>();
>> - if (AddrSize == 8 && RefAddrSize == 4)
>> - return makeFixedFormSizesArrayRef<8, 4>();
>> - if (AddrSize == 8 && RefAddrSize == 8)
>> - return makeFixedFormSizesArrayRef<8, 8>();
>> - return None;
>> -}
>> -
>> static const DWARFFormValue::FormClass DWARF4FormClasses[] = {
>> DWARFFormValue::FC_Unknown, // 0x0
>> DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
>> @@ -108,6 +54,214 @@ static const DWARFFormValue::FormClass D
>> DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
>> };
>>
>> +namespace {
>> +
>> +/// A helper class that can be used in DWARFFormValue.cpp functions that
>> need
>> +/// to know the byte size of DW_FORM values that vary in size depending
>> on the
>> +/// DWARF version, address byte size, or DWARF32 or DWARF64.
>> +class FormSizeHelper {
>> + uint16_t Version;
>> + uint8_t AddrSize;
>> + llvm::dwarf::DwarfFormat Format;
>> +
>> +public:
>> + FormSizeHelper(uint16_t V, uint8_t A, llvm::dwarf::DwarfFormat F)
>> + : Version(V), AddrSize(A), Format(F) {}
>> + uint8_t getAddressByteSize() const { return AddrSize; }
>> + uint8_t getRefAddrByteSize() const {
>> + if (Version == 2)
>> + return AddrSize;
>> + return getDwarfOffsetByteSize();
>> + }
>> + uint8_t getDwarfOffsetByteSize() const {
>> + switch (Format) {
>> + case dwarf::DwarfFormat::DWARF32:
>> + return 4;
>> + case dwarf::DwarfFormat::DWARF64:
>> + return 8;
>> + }
>> + llvm_unreachable("Invalid Format value");
>> + }
>> +};
>> +
>> +} // end anonymous namespace
>> +
>> +template <class T>
>> +static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const T *U) {
>> + switch (Form) {
>> + case DW_FORM_addr:
>> + if (U)
>> + return U->getAddressByteSize();
>> + return None;
>> +
>> + case DW_FORM_block: // ULEB128 length L followed by L bytes.
>> + case DW_FORM_block1: // 1 byte length L followed by L bytes.
>> + case DW_FORM_block2: // 2 byte length L followed by L bytes.
>> + case DW_FORM_block4: // 4 byte length L followed by L bytes.
>> + case DW_FORM_string: // C-string with null terminator.
>> + case DW_FORM_sdata: // SLEB128.
>> + case DW_FORM_udata: // ULEB128.
>> + case DW_FORM_ref_udata: // ULEB128.
>> + case DW_FORM_indirect: // ULEB128.
>> + case DW_FORM_exprloc: // ULEB128 length L followed by L bytes.
>> + case DW_FORM_strx: // ULEB128.
>> + case DW_FORM_addrx: // ULEB128.
>> + case DW_FORM_loclistx: // ULEB128.
>> + case DW_FORM_rnglistx: // ULEB128.
>> + case DW_FORM_GNU_addr_index: // ULEB128.
>> + case DW_FORM_GNU_str_index: // ULEB128.
>> + return None;
>> +
>> + case DW_FORM_ref_addr:
>> + if (U)
>> + return U->getRefAddrByteSize();
>> + return None;
>> +
>> + case DW_FORM_flag:
>> + case DW_FORM_data1:
>> + case DW_FORM_ref1:
>> + return 1;
>> +
>> + case DW_FORM_data2:
>> + case DW_FORM_ref2:
>> + return 2;
>> +
>> + case DW_FORM_data4:
>> + case DW_FORM_ref4:
>> + case DW_FORM_strp:
>
> DW_FORM_strp is a reference dependent on DWARF32/DWARF64.
>
>> + return 4;
>> +
>> + case DW_FORM_GNU_ref_alt:
>> + case DW_FORM_GNU_strp_alt:
>> + case DW_FORM_line_strp:
>> + case DW_FORM_sec_offset:
>> + case DW_FORM_strp_sup:
>> + case DW_FORM_ref_sup:
>> + if (U)
>> + return U->getDwarfOffsetByteSize();
>> + return None;
>> +
>> + case DW_FORM_data8:
>> + case DW_FORM_ref8:
>> + case DW_FORM_ref_sig8:
>> + return 8;
>> +
>> + case DW_FORM_flag_present:
>> + return 0;
>> +
>> + case DW_FORM_data16:
>> + return 16;
>> +
>> + case DW_FORM_implicit_const:
>> + // The implicit value is stored in the abbreviation as a ULEB128,
>> any
>> + // there no data in debug info.
>> + return 0;
>> +
>> + default:
>> + llvm_unreachable("Handle this form in this switch statement");
>> + }
>> + return None;
>> +}
>> +
>> +template <class T>
>> +static bool skipFormValue(dwarf::Form Form, const DataExtractor
>> &DebugInfoData,
>> + uint32_t *OffsetPtr, const T *U) {
>> + bool Indirect = false;
>> + do {
>> + switch (Form) {
>> + // Blocks if inlined data that have a length field and the data
>> bytes
>
> Blocks *of* inlined data...
>
>> + // inlined in the .debug_info.
>> + case DW_FORM_exprloc:
>> + case DW_FORM_block: {
>> + uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
>> + *OffsetPtr += size;
>> + return true;
>> + }
>> + case DW_FORM_block1: {
>> + uint8_t size = DebugInfoData.getU8(OffsetPtr);
>> + *OffsetPtr += size;
>> + return true;
>> + }
>> + case DW_FORM_block2: {
>> + uint16_t size = DebugInfoData.getU16(OffsetPtr);
>> + *OffsetPtr += size;
>> + return true;
>> + }
>> + case DW_FORM_block4: {
>> + uint32_t size = DebugInfoData.getU32(OffsetPtr);
>> + *OffsetPtr += size;
>> + return true;
>> + }
>> +
>> + // Inlined NULL terminated C-strings.
>> + case DW_FORM_string:
>> + DebugInfoData.getCStr(OffsetPtr);
>> + return true;
>> +
>> + case DW_FORM_addr:
>> + case DW_FORM_ref_addr:
>> + case DW_FORM_flag_present:
>> + case DW_FORM_data1:
>> + case DW_FORM_data2:
>> + case DW_FORM_data4:
>> + case DW_FORM_data8:
>> + case DW_FORM_flag:
>> + case DW_FORM_ref1:
>> + case DW_FORM_ref2:
>> + case DW_FORM_ref4:
>> + case DW_FORM_ref8:
>> + case DW_FORM_ref_sig8:
>> + case DW_FORM_sec_offset:
>> + case DW_FORM_strp:
>
> Missing DW_FORM_line_strp?
>
>> + case DW_FORM_GNU_ref_alt:
>> + case DW_FORM_GNU_strp_alt:
>> + if (Optional<uint8_t> FixedSize = ::getFixedByteSize(Form, U)) {
>> + *OffsetPtr += *FixedSize;
>> + return true;
>> + }
>> + return false;
>> +
>> + // signed or unsigned LEB 128 values.
>> + case DW_FORM_sdata:
>> + DebugInfoData.getSLEB128(OffsetPtr);
>> + return true;
>> +
>> + case DW_FORM_udata:
>> + case DW_FORM_ref_udata:
>> + case DW_FORM_strx:
>> + case DW_FORM_addrx:
>> + case DW_FORM_loclistx:
>> + case DW_FORM_rnglistx:
>> + case DW_FORM_GNU_addr_index:
>> + case DW_FORM_GNU_str_index:
>> + DebugInfoData.getULEB128(OffsetPtr);
>> + return true;
>> +
>> + case DW_FORM_indirect:
>> + Indirect = true;
>> + Form =
>> static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
>> + break;
>> +
>> + default:
>> + return false;
>> + }
>> + } while (Indirect);
>> + return true;
>> +}
>> +
>> +Optional<uint8_t> DWARFFormValue::getFixedByteSize(dwarf::Form Form,
>> + const DWARFUnit *U) {
>> + return ::getFixedByteSize(Form, U);
>> +}
>> +
>> +Optional<uint8_t>
>> +DWARFFormValue::getFixedByteSize(dwarf::Form Form, uint16_t Version,
>> + uint8_t AddrSize,
>> + llvm::dwarf::DwarfFormat Format) {
>> + FormSizeHelper FSH(Version, AddrSize, Format);
>> + return ::getFixedByteSize(Form, &FSH);
>> +}
>> +
>> bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
>> // First, check DWARF4 form classes.
>> if (Form < makeArrayRef(DWARF4FormClasses).size() &&
>> @@ -155,8 +309,7 @@ bool DWARFFormValue::extractValue(const
>> : U->getRefAddrByteSize();
>> RelocAddrMap::const_iterator AI = U->getRelocMap()-
>>> find(*offset_ptr);
>> if (AI != U->getRelocMap()->end()) {
>> - const std::pair<uint8_t, int64_t> &R = AI->second;
>> - Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second;
>> + Value.uval = data.getUnsigned(offset_ptr, AddrSize) + AI-
>>> second.second;
>> } else
>> Value.uval = data.getUnsigned(offset_ptr, AddrSize);
>> break;
>> @@ -188,7 +341,8 @@ bool DWARFFormValue::extractValue(const
>> Value.uval = data.getU16(offset_ptr);
>> break;
>> case DW_FORM_data4:
>> - case DW_FORM_ref4: {
>> + case DW_FORM_ref4:
>> + case DW_FORM_strp: {
>
> DW_FORM_strp depends on DWARF32/64 format. Moving it here is incorrect.
>
>> Value.uval = data.getU32(offset_ptr);
>> if (!U)
>> break;
>> @@ -216,15 +370,16 @@ bool DWARFFormValue::extractValue(const
>> indirect = true;
>> break;
>> case DW_FORM_sec_offset:
>> - case DW_FORM_strp:
>> case DW_FORM_GNU_ref_alt:
>> - case DW_FORM_GNU_strp_alt: {
>> - // FIXME: This is 64-bit for DWARF64.
>> - Value.uval = data.getU32(offset_ptr);
>> + case DW_FORM_GNU_strp_alt:
>> + case DW_FORM_line_strp:
>> + case DW_FORM_strp_sup:
>> + case DW_FORM_ref_sup: {
>> if (!U)
>> - break;
>> - RelocAddrMap::const_iterator AI =
>> - U->getRelocMap()->find(*offset_ptr - 4);
>> + return false;
>> + RelocAddrMap::const_iterator AI = U->getRelocMap()-
>>> find(*offset_ptr);
>> + uint8_t Size = U->getDwarfOffsetByteSize();
>> + Value.uval = data.getUnsigned(offset_ptr, Size);
>> if (AI != U->getRelocMap()->end())
>> Value.uval += AI->second.second;
>> break;
>> @@ -256,120 +411,22 @@ bool DWARFFormValue::extractValue(const
>> return true;
>> }
>>
>> -bool
>> -DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t*
>> offset_ptr,
>> - const DWARFUnit *U) const {
>> - return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, U);
>> -}
>> -
>> -bool
>> -DWARFFormValue::skipValue(dwarf::Form form, DataExtractor
>> debug_info_data,
>> - uint32_t *offset_ptr, const DWARFUnit *cu) {
>> - return skipValue(form, debug_info_data, offset_ptr, cu->getVersion(),
>> - cu->getAddressByteSize());
>> -}
>> -bool
>> -DWARFFormValue::skipValue(dwarf::Form form, DataExtractor
>> debug_info_data,
>> - uint32_t *offset_ptr, uint16_t Version,
>> - uint8_t AddrSize) {
>> - bool indirect = false;
>> - do {
>> - switch (form) {
>> - // Blocks if inlined data that have a length field and the data bytes
>> - // inlined in the .debug_info
>> - case DW_FORM_exprloc:
>> - case DW_FORM_block: {
>> - uint64_t size = debug_info_data.getULEB128(offset_ptr);
>> - *offset_ptr += size;
>> - return true;
>> - }
>> - case DW_FORM_block1: {
>> - uint8_t size = debug_info_data.getU8(offset_ptr);
>> - *offset_ptr += size;
>> - return true;
>> - }
>> - case DW_FORM_block2: {
>> - uint16_t size = debug_info_data.getU16(offset_ptr);
>> - *offset_ptr += size;
>> - return true;
>> - }
>> - case DW_FORM_block4: {
>> - uint32_t size = debug_info_data.getU32(offset_ptr);
>> - *offset_ptr += size;
>> - return true;
>> - }
>> -
>> - // Inlined NULL terminated C-strings
>> - case DW_FORM_string:
>> - debug_info_data.getCStr(offset_ptr);
>> - return true;
>> -
>> - // Compile unit address sized values
>> - case DW_FORM_addr:
>> - *offset_ptr += AddrSize;
>> - return true;
>> - case DW_FORM_ref_addr:
>> - *offset_ptr += getRefAddrSize(AddrSize, Version);
>> - return true;
>> -
>> - // 0 byte values - implied from the form.
>> - case DW_FORM_flag_present:
>> - return true;
>> -
>> - // 1 byte values
>> - case DW_FORM_data1:
>> - case DW_FORM_flag:
>> - case DW_FORM_ref1:
>> - *offset_ptr += 1;
>> - return true;
>> -
>> - // 2 byte values
>> - case DW_FORM_data2:
>> - case DW_FORM_ref2:
>> - *offset_ptr += 2;
>> - return true;
>> -
>> - // 4 byte values
>> - case DW_FORM_data4:
>> - case DW_FORM_ref4:
>> - *offset_ptr += 4;
>> - return true;
>> -
>> - // 8 byte values
>> - case DW_FORM_data8:
>> - case DW_FORM_ref8:
>> - case DW_FORM_ref_sig8:
>> - *offset_ptr += 8;
>> - return true;
>> -
>> - // signed or unsigned LEB 128 values
>> - // case DW_FORM_APPLE_db_str:
>> - case DW_FORM_sdata:
>> - case DW_FORM_udata:
>> - case DW_FORM_ref_udata:
>> - case DW_FORM_GNU_str_index:
>> - case DW_FORM_GNU_addr_index:
>> - debug_info_data.getULEB128(offset_ptr);
>> - return true;
>> -
>> - case DW_FORM_indirect:
>> - indirect = true;
>> - form =
>> static_cast<dwarf::Form>(debug_info_data.getULEB128(offset_ptr));
>> - break;
>> -
>> - // FIXME: 4 for DWARF32, 8 for DWARF64.
>> - case DW_FORM_sec_offset:
>> - case DW_FORM_strp:
>> - case DW_FORM_GNU_ref_alt:
>> - case DW_FORM_GNU_strp_alt:
>> - *offset_ptr += 4;
>> - return true;
>> -
>> - default:
>> - return false;
>> - }
>> - } while (indirect);
>> - return true;
>> +bool DWARFFormValue::skipValue(DataExtractor DebugInfoData,
>> + uint32_t *offset_ptr, const DWARFUnit *U)
>> const {
>> + return DWARFFormValue::skipValue(Form, DebugInfoData, offset_ptr, U);
>> +}
>> +
>> +bool DWARFFormValue::skipValue(dwarf::Form form, DataExtractor
>> DebugInfoData,
>> + uint32_t *offset_ptr, const DWARFUnit *U)
>> {
>> + return skipFormValue(form, DebugInfoData, offset_ptr, U);
>> +}
>> +
>> +bool DWARFFormValue::skipValue(dwarf::Form form, DataExtractor
>> DebugInfoData,
>> + uint32_t *offset_ptr, uint16_t Version,
>> + uint8_t AddrSize,
>> + llvm::dwarf::DwarfFormat Format) {
>> + FormSizeHelper FSH(Version, AddrSize, Format);
>> + return skipFormValue(form, DebugInfoData, offset_ptr, &FSH);
>> }
>>
>> void
>> @@ -556,8 +613,9 @@ Optional<uint64_t> DWARFFormValue::getAs
>> return None;
>> return Value.uval + U->getOffset();
>> case DW_FORM_ref_addr:
>> + case DW_FORM_ref_sig8:
>> + case DW_FORM_GNU_ref_alt:
>> return Value.uval;
>> - // FIXME: Add proper support for DW_FORM_ref_sig8 and
>> DW_FORM_GNU_ref_alt.
>> default:
>> return None;
>> }
>>
>> Modified: llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwp/llvm-
>> dwp.cpp?rev=286597&r1=286596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp (original)
>> +++ llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp Fri Nov 11 10:21:37 2016
>> @@ -133,7 +133,14 @@ static Expected<CompileUnitIdentifiers>
>> StringRef Str) {
>> uint32_t Offset = 0;
>> DataExtractor InfoData(Info, true, 0);
>> - InfoData.getU32(&Offset); // Length
>> + dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32;
>> + uint64_t Length = InfoData.getU32(&Offset);
>> + // If the length is 0xffffffff, then this indictes that this is a DWARF
>> 64
>> + // stream and the length is actually encoded into a 64 bit value that
>> follows.
>> + if (Length == 0xffffffffU) {
>> + Format = dwarf::DwarfFormat::DWARF64;
>> + Length = InfoData.getU64(&Offset);
>> + }
>> uint16_t Version = InfoData.getU16(&Offset);
>> InfoData.getU32(&Offset); // Abbrev offset (should be zero)
>> uint8_t AddrSize = InfoData.getU8(&Offset);
>> @@ -174,7 +181,8 @@ static Expected<CompileUnitIdentifiers>
>> ID.Signature = InfoData.getU64(&Offset);
>> break;
>> default:
>> - DWARFFormValue::skipValue(Form, InfoData, &Offset, Version,
>> AddrSize);
>> + DWARFFormValue::skipValue(Form, InfoData, &Offset, Version,
>> AddrSize,
>> + Format);
>> }
>> }
>> return ID;
>>
>> Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp?rev=28
>> 6597&r1=286596&r2=286597&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp (original)
>> +++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp Fri Nov 11
>> 10:21:37 2016
>> @@ -21,16 +21,47 @@ using namespace dwarf;
>> namespace {
>>
>> TEST(DWARFFormValue, FixedFormSizes) {
>> - // Size of DW_FORM_addr and DW_FORM_ref_addr are equal in DWARF2,
>> - // DW_FORM_ref_addr is always 4 bytes in DWARF32 starting from DWARF3.
>> - ArrayRef<uint8_t> sizes = DWARFFormValue::getFixedFormSizes(4, 2);
>> - EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
>> - sizes = DWARFFormValue::getFixedFormSizes(8, 2);
>> - EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
>> - sizes = DWARFFormValue::getFixedFormSizes(8, 3);
>> - EXPECT_EQ(4, sizes[DW_FORM_ref_addr]);
>> - // Check that we don't have fixed form sizes for weird address sizes.
>> - EXPECT_EQ(0U, DWARFFormValue::getFixedFormSizes(16, 2).size());
>> + Optional<uint8_t> RefSize;
>> + Optional<uint8_t> AddrSize;
>> + // Test 32 bit DWARF version 2 with 4 byte addresses.
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4,
>> DWARF32);
>> + AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 4,
>> DWARF32);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_TRUE(AddrSize.hasValue());
>> + EXPECT_EQ(*RefSize, *AddrSize);
>> +
>> + // Test 32 bit DWARF version 2 with 8 byte addresses.
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8,
>> DWARF32);
>> + AddrSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 2, 8,
>> DWARF32);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_TRUE(AddrSize.hasValue());
>> + EXPECT_EQ(*RefSize, *AddrSize);
>> +
>> + // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and
>> beyond.
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 4,
>> DWARF32);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 4);
>> +
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 4,
>> DWARF32);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 4);
>> +
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 4,
>> DWARF32);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 4);
>> +
>> + // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and
>> beyond.
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 3, 8,
>> DWARF64);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 8);
>> +
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 4, 8,
>> DWARF64);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 8);
>> +
>> + RefSize = DWARFFormValue::getFixedByteSize(DW_FORM_ref_addr, 5, 8,
>> DWARF64);
>> + EXPECT_TRUE(RefSize.hasValue());
>> + EXPECT_EQ(*RefSize, 8);
>> }
>>
>> bool isFormClass(dwarf::Form Form, DWARFFormValue::FormClass FC) {
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list