[llvm] r286597 - Clean up DWARFFormValue by reducing duplicated code and removing DWARFFormValue::getFixedFormSizes()

Robinson, Paul via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 11 09:53:47 PST 2016



> -----Original Message-----
> From: Greg Clayton [mailto:gclayton at apple.com]
> Sent: Friday, November 11, 2016 9:49 AM
> To: Robinson, Paul
> Cc: llvm-commits at lists.llvm.org
> Subject: Re: [llvm] r286597 - Clean up DWARFFormValue by reducing
> duplicated code and removing DWARFFormValue::getFixedFormSizes()
> 
> 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?

Please do.  A much bigger chunk of my time is going to debug-info
stuff now.
--paulr

> 
> 
> > 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