[llvm] 6d0be74 - llvm-dwarfdump: Don't try to parse rnglist tables when dumping CUs

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 4 19:18:25 PDT 2020


Author: David Blaikie
Date: 2020-10-04T19:18:14-07:00
New Revision: 6d0be74af5555f7bc56ac72cbd98ff270fd1291b

URL: https://github.com/llvm/llvm-project/commit/6d0be74af5555f7bc56ac72cbd98ff270fd1291b
DIFF: https://github.com/llvm/llvm-project/commit/6d0be74af5555f7bc56ac72cbd98ff270fd1291b.diff

LOG: llvm-dwarfdump: Don't try to parse rnglist tables when dumping CUs

It's not possible to do this in complete generality - a CU using a
sec_offset DW_AT_ranges has no way of knowing where its rnglists
contribution starts, so should not attempt to parse any full rnglist
table/header to do so. And even using FORM_rnglistx there's no need to
parse the header - the offset can be computed using the CU's DWARF
format (32 or 64) to compute offset entry sizes, and then the list
parsed at that offset without ever trying to find a rnglist contribution
header immediately prior to the rnglists_base.

Added: 
    

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
    llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/test/DebugInfo/X86/dwarfdump-rnglists-dwarf64.s
    llvm/test/DebugInfo/X86/dwarfdump-rnglists.s
    llvm/test/tools/llvm-dwarfdump/X86/tombstone.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index ee9f7adb96c4..8f58b4e6458e 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -116,9 +116,15 @@ class DWARFListTableHeader {
     if (Index > HeaderData.OffsetEntryCount)
       return None;
 
+    return getOffsetEntry(Data, getHeaderOffset() + getHeaderSize(Format), Format, Index);
+  }
+
+  static Optional<uint64_t> getOffsetEntry(DataExtractor Data,
+                                           uint64_t OffsetTableOffset,
+                                           dwarf::DwarfFormat Format,
+                                           uint32_t Index) {
     uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
-    uint64_t Offset =
-        getHeaderOffset() + getHeaderSize(Format) + OffsetByteSize * Index;
+    uint64_t Offset = OffsetTableOffset + OffsetByteSize * Index;
     auto R = Data.getUnsigned(&Offset, OffsetByteSize);
     return R;
   }
@@ -272,9 +278,10 @@ DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
                                             uint64_t Offset) {
   // Extract the list from the section and enter it into the list map.
   DWARFListType List;
-  Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
+  if (Header.length())
+    Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
   if (Error E =
-          List.extract(Data, getHeaderOffset(), &Offset,
+          List.extract(Data, Header.length() ? getHeaderOffset() : 0, &Offset,
                        Header.getSectionName(), Header.getListTypeString()))
     return std::move(E);
   return List;

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index d0664c271fb5..0b0238f7235e 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -229,7 +229,6 @@ class DWARFUnit {
   Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
 
   /// A table of range lists (DWARF v5 and later).
-  Optional<DWARFDebugRnglistTable> RngListTable;
   Optional<DWARFListTableHeader> LoclistTableHeader;
 
   mutable const DWARFAbbreviationDeclarationSet *Abbrevs;

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index b871e6ebdca5..67066db15b4a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -503,27 +503,9 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
               DWARFListTableHeader::getHeaderSize(Header.getFormat()));
     } else
       setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
-                       toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
-    if (RangeSection->Data.size()) {
-      // Parse the range list table header. Individual range lists are
-      // extracted lazily.
-      DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
-                                  isLittleEndian, 0);
-      auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
-          RangesDA, RangeSectionBase, Header.getFormat());
-      if (!TableOrError)
-        return createStringError(errc::invalid_argument,
-                                 "parsing a range list table: " +
-                                     toString(TableOrError.takeError()));
-
-      RngListTable = TableOrError.get();
-
-      // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
-      // Adjust RangeSectionBase to point past the table header.
-      if (IsDWO && RngListTable)
-        RangeSectionBase =
-            ContributionBaseOffset + RngListTable->getHeaderSize();
-    }
+                       toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
+                                       DWARFListTableHeader::getHeaderSize(
+                                           Header.getFormat())));
 
     // In a split dwarf unit, there is no DW_AT_loclists_base attribute.
     // Setting LocSectionBase to point past the table header.
@@ -602,19 +584,8 @@ bool DWARFUnit::parseDWO() {
   if (AddrOffsetSectionBase)
     DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
   if (getVersion() >= 5) {
-    DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
-    DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
-                                isLittleEndian, 0);
-    if (auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
-            RangesDA, RangeSectionBase, Header.getFormat()))
-      DWO->RngListTable = TableOrError.get();
-    else
-      Context.getRecoverableErrorHandler()(createStringError(
-          errc::invalid_argument, "parsing a range list table: %s",
-          toString(TableOrError.takeError()).c_str()));
-
-    if (DWO->RngListTable)
-      DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
+    DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
+                          DWARFListTableHeader::getHeaderSize(getFormat()));
   } else {
     auto DWORangesBase = UnitDie.getRangesBaseAttribute();
     DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
@@ -638,17 +609,13 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
       return std::move(E);
     return RangeList.getAbsoluteRanges(getBaseAddress());
   }
-  if (RngListTable) {
-    DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
-                                  isLittleEndian, RngListTable->getAddrSize());
-    auto RangeListOrError = RngListTable->findList(RangesData, Offset);
-    if (RangeListOrError)
-      return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
-    return RangeListOrError.takeError();
-  }
-
-  return createStringError(errc::invalid_argument,
-                           "missing or invalid range list table");
+  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+                                isLittleEndian, Header.getAddressByteSize());
+  DWARFDebugRnglistTable RnglistTable;
+  auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
+  if (RangeListOrError)
+    return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
+  return RangeListOrError.takeError();
 }
 
 Expected<DWARFAddressRangesVector>
@@ -656,12 +623,10 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
   if (auto Offset = getRnglistOffset(Index))
     return findRnglistFromOffset(*Offset);
 
-  if (RngListTable)
-    return createStringError(errc::invalid_argument,
-                             "invalid range list table index %d", Index);
-
   return createStringError(errc::invalid_argument,
-                           "missing or invalid range list table");
+                           "invalid range list table index %d (possibly "
+                           "missing the entire range list table)",
+                           Index);
 }
 
 Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
@@ -1007,11 +972,12 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
 }
 
 Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
-  if (!RngListTable)
-    return None;
   DataExtractor RangesData(RangeSection->Data, isLittleEndian,
                            getAddressByteSize());
-  if (Optional<uint64_t> Off = RngListTable->getOffsetEntry(RangesData, Index))
+  DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
+                              isLittleEndian, 0);
+  if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
+          RangesData, RangeSectionBase, getFormat(), Index))
     return *Off + RangeSectionBase;
   return None;
 }

diff  --git a/llvm/test/DebugInfo/X86/dwarfdump-rnglists-dwarf64.s b/llvm/test/DebugInfo/X86/dwarfdump-rnglists-dwarf64.s
index f6c8751083f3..5c8eaffe001c 100644
--- a/llvm/test/DebugInfo/X86/dwarfdump-rnglists-dwarf64.s
+++ b/llvm/test/DebugInfo/X86/dwarfdump-rnglists-dwarf64.s
@@ -1,8 +1,8 @@
 # RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
 # RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
-# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
+# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR --implicit-check-not=error
 # RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
-# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
+# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR --implicit-check-not=error
 # RUN: llvm-dwarfdump -debug-rnglists %t.o | \
 # RUN:   FileCheck %s --check-prefix=RNGLISTS
 
@@ -209,8 +209,7 @@ Range1_end:
 # CHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000025
 # CHECK-NEXT: [0x0000002a, 0x00000034))
 
-#ERR: error: parsing a range list table: did not detect a valid list table with base = 0x8
-#ERR: error: decoding address ranges: missing or invalid range list table
+#ERR: error: decoding address ranges: invalid range list offset 0x4000500000008
 #ERR: error: decoding address ranges: invalid range list offset 0xfa0
 
 # RNGLISTS:      .debug_rnglists contents:

diff  --git a/llvm/test/DebugInfo/X86/dwarfdump-rnglists.s b/llvm/test/DebugInfo/X86/dwarfdump-rnglists.s
index 45cf65c985f8..74de6427df71 100644
--- a/llvm/test/DebugInfo/X86/dwarfdump-rnglists.s
+++ b/llvm/test/DebugInfo/X86/dwarfdump-rnglists.s
@@ -1,8 +1,8 @@
 # RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
 # RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
-# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
+# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR --implicit-check-not=error
 # RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
-# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
+# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR --implicit-check-not=error
 
 # Test object to verify dwarfdump handles v5 range lists.
 # We use very simplified compile unit dies.
@@ -203,6 +203,4 @@ Range1_end:
 # CHECK-NEXT: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000015
 # CHECK-NEXT: [0x0000002a, 0x00000034))
 
-#ERR: error: parsing a range list table: did not detect a valid list table with base = 0x8
-#ERR: error: decoding address ranges: missing or invalid range list table
 #ERR: error: decoding address ranges: invalid range list offset 0xfa0

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/tombstone.s b/llvm/test/tools/llvm-dwarfdump/X86/tombstone.s
index 3465d08bf261..7b4ff70e5ff5 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/tombstone.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/tombstone.s
@@ -1,7 +1,5 @@
 # RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o %t.o
-# RUN: not llvm-dwarfdump -v -debug-info -debug-line -debug-addr -debug-rnglists -debug-ranges %t.o | FileCheck --implicit-check-not=DW_TAG --implicit-check-not=DW_AT %s
-
-# FIXME: Remove the 'not' once the rnglist are lazily/correctly parsed (see comment below)
+# RUN: llvm-dwarfdump -v -debug-info -debug-line -debug-addr -debug-rnglists -debug-ranges %t.o | FileCheck --implicit-check-not=DW_TAG --implicit-check-not=DW_AT %s
 
 # Test that llvm - dwarfdump strips addresses relating to dead code(using the
 # DWARFv6 - proposed tombstone constant & nearest equivalent for debug_ranges)
@@ -45,17 +43,14 @@
 # CHECK:     DW_TAG_compile_unit
 # CHECK:       DW_AT_addr_base
 
-# FIXME: Lazily parse rnglists rather than expecting to be able to parse an
-#        entire rnglists contribution (since there's no way to know where such a
-#        contribution starts) - rather than assuming one starts at 0.
 
 # CHECK:       DW_AT_ranges
-#     [0x0000000000000042, 0x0000000000000048)
-#     [0x0000000000000042, 0x0000000000000048)
-#     [0x0000000000000042, 0x0000000000000048)
-#     [0x0000000000000042, 0x0000000000000042)
-#     [0x0000000000000042, 0x0000000000000048)
-#     [0x0000000000000042, 0x0000000000000048))
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000048)
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000048)
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000048)
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000042)
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000048)
+# CHECK-NEXT:    [0x0000000000000042, 0x0000000000000048))
 # CHECK:       DW_TAG_subprogram
 # CHECK:         DW_AT_low_pc [DW_FORM_addrx]     (indexed (00000000) address = 0xffffffffffffffff (dead code))
 # CHECK:         DW_AT_high_pc [DW_FORM_data4]   (0x00000006)


        


More information about the llvm-commits mailing list