[llvm] r371014 - [DWARF] Support DWARF64 in DWARFListTableHeader.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 23:49:05 PDT 2019


Author: ikudrin
Date: Wed Sep  4 23:49:05 2019
New Revision: 371014

URL: http://llvm.org/viewvc/llvm-project?rev=371014&view=rev
Log:
[DWARF] Support DWARF64 in DWARFListTableHeader.

This enables 64-bit DWARF support for parsing range and location list tables.

Differential Revision: https://reviews.llvm.org/D66643

Added:
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s
Removed:
    llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h Wed Sep  4 23:49:05 2019
@@ -57,7 +57,7 @@ class DWARFListTableHeader {
   struct Header {
     /// The total length of the entries for this table, not including the length
     /// field itself.
-    uint32_t Length = 0;
+    uint64_t Length = 0;
     /// The DWARF version number.
     uint16_t Version;
     /// The size in bytes of an address on the target architecture. For
@@ -75,7 +75,7 @@ class DWARFListTableHeader {
   /// The offset table, which contains offsets to the individual list entries.
   /// It is used by forms such as DW_FORM_rnglistx.
   /// FIXME: Generate the table and use the appropriate forms.
-  std::vector<uint32_t> Offsets;
+  std::vector<uint64_t> Offsets;
   /// The table's format, either DWARF32 or DWARF64.
   dwarf::DwarfFormat Format;
   /// The offset at which the header (and hence the table) is located within
@@ -97,14 +97,26 @@ public:
   }
   uint64_t getHeaderOffset() const { return HeaderOffset; }
   uint8_t getAddrSize() const { return HeaderData.AddrSize; }
-  uint32_t getLength() const { return HeaderData.Length; }
+  uint64_t getLength() const { return HeaderData.Length; }
   uint16_t getVersion() const { return HeaderData.Version; }
   StringRef getSectionName() const { return SectionName; }
   StringRef getListTypeString() const { return ListTypeString; }
   dwarf::DwarfFormat getFormat() const { return Format; }
 
+  /// Return the size of the table header including the length but not including
+  /// the offsets.
+  static uint8_t getHeaderSize(dwarf::DwarfFormat Format) {
+    switch (Format) {
+    case dwarf::DwarfFormat::DWARF32:
+      return 12;
+    case dwarf::DwarfFormat::DWARF64:
+      return 20;
+    }
+    llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+  }
+
   void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
-  Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+  Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
     if (Index < Offsets.size())
       return Offsets[Index];
     return None;
@@ -116,7 +128,7 @@ public:
   /// Returns the length of the table, including the length field, or 0 if the
   /// length has not been determined (e.g. because the table has not yet been
   /// parsed, or there was a problem in parsing).
-  uint32_t length() const;
+  uint64_t length() const;
 };
 
 /// A class representing a table of lists as specified in the DWARF v5
@@ -155,6 +167,7 @@ public:
 
   uint64_t getHeaderOffset() const { return Header.getHeaderOffset(); }
   uint8_t getAddrSize() const { return Header.getAddrSize(); }
+  dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
 
   void dump(raw_ostream &OS,
             llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
@@ -162,23 +175,17 @@ public:
             DIDumpOptions DumpOpts = {}) const;
 
   /// Return the contents of the offset entry designated by a given index.
-  Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+  Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
     return Header.getOffsetEntry(Index);
   }
   /// Return the size of the table header including the length but not including
   /// the offsets. This is dependent on the table format, which is unambiguously
   /// derived from parsing the table.
   uint8_t getHeaderSize() const {
-    switch (Header.getFormat()) {
-    case dwarf::DwarfFormat::DWARF32:
-      return 12;
-    case dwarf::DwarfFormat::DWARF64:
-      return 20;
-    }
-    llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+    return DWARFListTableHeader::getHeaderSize(getFormat());
   }
 
-  uint32_t length() { return Header.length(); }
+  uint64_t length() { return Header.length(); }
 };
 
 template <typename DWARFListType>

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=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Sep  4 23:49:05 2019
@@ -416,7 +416,7 @@ public:
   /// Return a rangelist's offset based on an index. The index designates
   /// an entry in the rangelist table's offset array and is supplied by
   /// DW_FORM_rnglistx.
-  Optional<uint32_t> getRnglistOffset(uint32_t Index) {
+  Optional<uint64_t> getRnglistOffset(uint32_t Index) {
     if (RngListTable)
       return RngListTable->getOffsetEntry(Index);
     return None;

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp Wed Sep  4 23:49:05 2019
@@ -24,25 +24,34 @@ Error DWARFListTableHeader::extract(DWAR
                        "section is not large enough to contain a "
                        "%s table length at offset 0x%" PRIx64,
                        SectionName.data(), *OffsetPtr);
-  // TODO: Add support for DWARF64.
-  HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
-  if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64)
-    return createStringError(errc::not_supported,
-                       "DWARF64 is not supported in %s at offset 0x%" PRIx64,
-                       SectionName.data(), HeaderOffset);
   Format = dwarf::DwarfFormat::DWARF32;
-  if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
+  uint8_t OffsetByteSize = 4;
+  HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
+  if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
+    Format = dwarf::DwarfFormat::DWARF64;
+    OffsetByteSize = 8;
+    HeaderData.Length = Data.getU64(OffsetPtr);
+  } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
+    return createStringError(errc::invalid_argument,
+        "%s table at offset 0x%" PRIx64
+        " has unsupported reserved unit length of value 0x%8.8" PRIx64,
+        SectionName.data(), HeaderOffset, HeaderData.Length);
+  }
+  uint64_t FullLength =
+      HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+  assert(FullLength == length());
+  if (FullLength < getHeaderSize(Format))
     return createStringError(errc::invalid_argument,
                        "%s table at offset 0x%" PRIx64
-                       " has too small length (0x%" PRIx32
+                       " has too small length (0x%" PRIx64
                        ") to contain a complete header",
-                       SectionName.data(), HeaderOffset, length());
-  uint64_t End = HeaderOffset + length();
-  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
+                       SectionName.data(), HeaderOffset, FullLength);
+  uint64_t End = HeaderOffset + FullLength;
+  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
     return createStringError(errc::invalid_argument,
                        "section is not large enough to contain a %s table "
-                       "of length 0x%" PRIx32 " at offset 0x%" PRIx64,
-                       SectionName.data(), length(), HeaderOffset);
+                       "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
+                       SectionName.data(), FullLength, HeaderOffset);
 
   HeaderData.Version = Data.getU16(OffsetPtr);
   HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -65,15 +74,15 @@ Error DWARFListTableHeader::extract(DWAR
                        "%s table at offset 0x%" PRIx64
                        " has unsupported segment selector size %" PRIu8,
                        SectionName.data(), HeaderOffset, HeaderData.SegSize);
-  if (End < HeaderOffset + sizeof(HeaderData) +
-                HeaderData.OffsetEntryCount * sizeof(uint32_t))
+  if (End < HeaderOffset + getHeaderSize(Format) +
+                HeaderData.OffsetEntryCount * OffsetByteSize)
     return createStringError(errc::invalid_argument,
         "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
         ") than there is space for",
         SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
   Data.setAddressSize(HeaderData.AddrSize);
   for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
-    Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
+    Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
   return Error::success();
 }
 
@@ -81,7 +90,7 @@ void DWARFListTableHeader::dump(raw_ostr
   if (DumpOpts.Verbose)
     OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
   OS << format(
-      "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", "
+      "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", "
       "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
       ", offset_entry_count = "
       "0x%8.8" PRIx32 "\n",
@@ -91,18 +100,17 @@ void DWARFListTableHeader::dump(raw_ostr
   if (HeaderData.OffsetEntryCount > 0) {
     OS << "offsets: [";
     for (const auto &Off : Offsets) {
-      OS << format("\n0x%8.8" PRIx32, Off);
+      OS << format("\n0x%8.8" PRIx64, Off);
       if (DumpOpts.Verbose)
         OS << format(" => 0x%8.8" PRIx64,
-                     Off + HeaderOffset + sizeof(HeaderData));
+                     Off + HeaderOffset + getHeaderSize(Format));
     }
     OS << "\n]\n";
   }
 }
 
-uint32_t DWARFListTableHeader::length() const {
+uint64_t DWARFListTableHeader::length() const {
   if (HeaderData.Length == 0)
     return 0;
-  // TODO: DWARF64 support.
-  return HeaderData.Length + sizeof(uint32_t);
+  return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
 }

Removed: llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s?rev=371013&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s (removed)
@@ -1,2 +0,0 @@
-.section .debug_rnglists,"", at progbits
-.long 0xffffffff  # Unsupported DWARF64 format

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s?rev=371014&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s Wed Sep  4 23:49:05 2019
@@ -0,0 +1,39 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN:   llvm-dwarfdump -v --debug-rnglists - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_rnglists contents:
+# CHECK-NEXT: 0x00000000: range list header:
+# CHECK-SAME:   length = 0x0000001a,
+# CHECK-SAME:   version = 0x0005,
+# CHECK-SAME:   addr_size = 0x08,
+# CHECK-SAME:   seg_size = 0x00,
+# CHECK-SAME:   offset_entry_count = 0x00000002
+# CHECK-NEXT: offsets: [
+# CHECK-NEXT: 0x00000010 => 0x00000024
+# CHECK-NEXT: 0x00000011 => 0x00000025
+# CHECK-NEXT: ]
+# CHECK-NEXT: ranges:
+# CHECK-NEXT: 0x00000024: [DW_RLE_end_of_list]
+# CHECK-NEXT: 0x00000025: [DW_RLE_end_of_list]
+
+    .section .debug_rnglists,"", at progbits
+    .long 0xffffffff         # DWARF64 mark
+    .quad .Lend - .Lversion  # Table length
+.Lversion:
+    .short 5                 # Version
+    .byte 8                  # Address size
+    .byte 0                  # Segment selector size
+    .long 2                  # Offset entry count
+
+.Loffsets:
+    .quad .Ltable0 - .Loffsets
+    .quad .Ltable1 - .Loffsets
+
+.Ltable0:
+    .byte 0          # DW_RLE_end_of_list
+
+.Ltable1:
+    .byte 0          # DW_RLE_end_of_list
+
+.Lend:

Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s Wed Sep  4 23:49:05 2019
@@ -37,11 +37,6 @@
 # CHECK-NEXT: error: section is not large enough to contain a .debug_rnglists table of length 0x1f at offset 0xe5
 # CHECK-NOT: error:
 
-# RUN: llvm-mc %S/Inputs/debug_rnglists_DWARF64.s -filetype obj -triple x86_64-pc-linux -o - | \
-# RUN: llvm-dwarfdump --debug-rnglists - 2>&1 | FileCheck %s --check-prefix=DWARF64
-
-# DWARF64: DWARF64 is not supported in .debug_rnglists at offset 0x0
-
 .section .debug_rnglists,"", at progbits
 
 # Table 1 (good)

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s?rev=371014&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s Wed Sep  4 23:49:05 2019
@@ -0,0 +1,8 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN:   llvm-dwarfdump --debug-rnglists - 2>&1 | \
+# RUN:   FileCheck %s --implicit-check-not=error
+
+# CHECK: error: .debug_rnglists table at offset 0x0 has unsupported reserved unit length of value 0xfffffff0
+
+.section .debug_rnglists,"", at progbits
+.long 0xfffffff0




More information about the llvm-commits mailing list