[llvm] ad68a8b - DebugInfo: Cleanup RLE dumping, using a length-constrained DataExtractor rather than carrying the end offset separately

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 18 19:32:52 PDT 2020


Author: David Blaikie
Date: 2020-09-18T19:32:38-07:00
New Revision: ad68a8b9526601c5a778d74b33e2d660fbc52772

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

LOG: DebugInfo: Cleanup RLE dumping, using a length-constrained DataExtractor rather than carrying the end offset separately

Added: 
    

Modified: 
    llvm/include/llvm/BinaryFormat/Dwarf.h
    llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
    llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
    llvm/lib/BinaryFormat/Dwarf.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
    llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 28cbc2c6a0e4..6558a74b6411 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -553,6 +553,7 @@ StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
 StringRef IndexString(unsigned Idx);
 StringRef FormatString(DwarfFormat Format);
 StringRef FormatString(bool IsDWARF64);
+StringRef RLEString(unsigned RLE);
 /// @}
 
 /// \defgroup DwarfConstantsParsing Dwarf constants parsing functions

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index 88e5432851d6..78a018ff482b 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -34,7 +34,7 @@ struct RangeListEntry : public DWARFListEntryBase {
   uint64_t Value0;
   uint64_t Value1;
 
-  Error extract(DWARFDataExtractor Data, uint64_t End, uint64_t *OffsetPtr);
+  Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
   void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
             uint64_t &CurrentBase, DIDumpOptions DumpOpts,
             llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index e54bed2d65d6..ee9f7adb96c4 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -46,7 +46,7 @@ template <typename ListEntryType> class DWARFListType {
   const ListEntries &getEntries() const { return Entries; }
   bool empty() const { return Entries.empty(); }
   void clear() { Entries.clear(); }
-  Error extract(DWARFDataExtractor Data, uint64_t HeaderOffset, uint64_t End,
+  Error extract(DWARFDataExtractor Data, uint64_t HeaderOffset,
                 uint64_t *OffsetPtr, StringRef SectionName,
                 StringRef ListStringName);
 };
@@ -197,18 +197,18 @@ Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
     return E;
 
   Data.setAddressSize(Header.getAddrSize());
-  uint64_t End = getHeaderOffset() + Header.length();
-  while (*OffsetPtr < End) {
+  Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
+  while (Data.isValidOffset(*OffsetPtr)) {
     DWARFListType CurrentList;
     uint64_t Off = *OffsetPtr;
-    if (Error E = CurrentList.extract(Data, getHeaderOffset(), End, OffsetPtr,
+    if (Error E = CurrentList.extract(Data, getHeaderOffset(), OffsetPtr,
                                       Header.getSectionName(),
                                       Header.getListTypeString()))
       return E;
     ListMap[Off] = CurrentList;
   }
 
-  assert(*OffsetPtr == End &&
+  assert(*OffsetPtr == Data.size() &&
          "mismatch between expected length of table and length "
          "of extracted data");
   return Error::success();
@@ -216,18 +216,18 @@ Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
 
 template <typename ListEntryType>
 Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
-                                            uint64_t HeaderOffset, uint64_t End,
+                                            uint64_t HeaderOffset,
                                             uint64_t *OffsetPtr,
                                             StringRef SectionName,
                                             StringRef ListTypeString) {
-  if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
+  if (*OffsetPtr < HeaderOffset || *OffsetPtr >= Data.size())
     return createStringError(errc::invalid_argument,
                        "invalid %s list offset 0x%" PRIx64,
                        ListTypeString.data(), *OffsetPtr);
   Entries.clear();
-  while (*OffsetPtr < End) {
+  while (Data.isValidOffset(*OffsetPtr)) {
     ListEntryType Entry;
-    if (Error E = Entry.extract(Data, End, OffsetPtr))
+    if (Error E = Entry.extract(Data, OffsetPtr))
       return E;
     Entries.push_back(Entry);
     if (Entry.isSentinel())
@@ -272,9 +272,9 @@ DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
                                             uint64_t Offset) {
   // Extract the list from the section and enter it into the list map.
   DWARFListType List;
-  uint64_t End = getHeaderOffset() + Header.length();
+  Data = DWARFDataExtractor(Data, getHeaderOffset() + Header.length());
   if (Error E =
-          List.extract(Data, getHeaderOffset(), End, &Offset,
+          List.extract(Data, getHeaderOffset(), &Offset,
                        Header.getSectionName(), Header.getListTypeString()))
     return std::move(E);
   return List;

diff  --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index a35ef611ae2e..29028709d378 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -795,6 +795,17 @@ StringRef llvm::dwarf::FormatString(bool IsDWARF64) {
   return FormatString(IsDWARF64 ? DWARF64 : DWARF32);
 }
 
+StringRef llvm::dwarf::RLEString(unsigned RLE) {
+  switch (RLE) {
+  default:
+    return StringRef();
+#define HANDLE_DW_RLE(ID, NAME)                                                \
+  case DW_RLE_##NAME:                                                          \
+    return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+  }
+}
+
 constexpr char llvm::dwarf::EnumTraits<Attribute>::Type[];
 constexpr char llvm::dwarf::EnumTraits<Form>::Type[];
 constexpr char llvm::dwarf::EnumTraits<Index>::Type[];

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 9ae4c5b73ebe..d517e51e7e36 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -16,98 +16,73 @@
 
 using namespace llvm;
 
-Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End,
-                              uint64_t *OffsetPtr) {
+Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
   Offset = *OffsetPtr;
   SectionIndex = -1ULL;
   // The caller should guarantee that we have at least 1 byte available, so
   // we just assert instead of revalidate.
-  assert(*OffsetPtr < End &&
+  assert(*OffsetPtr < Data.size() &&
          "not enough space to extract a rangelist encoding");
   uint8_t Encoding = Data.getU8(OffsetPtr);
 
+  DataExtractor::Cursor C(*OffsetPtr);
   switch (Encoding) {
   case dwarf::DW_RLE_end_of_list:
     Value0 = Value1 = 0;
     break;
   // TODO: Support other encodings.
   case dwarf::DW_RLE_base_addressx: {
-    uint64_t PreviousOffset = *OffsetPtr - 1;
-    Value0 = Data.getULEB128(OffsetPtr);
-    if (End < *OffsetPtr)
-      return createStringError(
-          errc::invalid_argument,
-          "read past end of table when reading "
-          "DW_RLE_base_addressx encoding at offset 0x%" PRIx64,
-          PreviousOffset);
+    Value0 = Data.getULEB128(C);
     break;
   }
   case dwarf::DW_RLE_startx_endx:
-    return createStringError(errc::not_supported,
-                       "unsupported rnglists encoding DW_RLE_startx_endx at "
-                       "offset 0x%" PRIx64,
-                       *OffsetPtr - 1);
+    consumeError(C.takeError());
+    return createStringError(
+        errc::not_supported,
+        "unsupported rnglists encoding DW_RLE_startx_endx at "
+        "offset 0x%" PRIx64,
+        Offset);
   case dwarf::DW_RLE_startx_length: {
-    uint64_t PreviousOffset = *OffsetPtr - 1;
-    Value0 = Data.getULEB128(OffsetPtr);
-    Value1 = Data.getULEB128(OffsetPtr);
-    if (End < *OffsetPtr)
-      return createStringError(
-          errc::invalid_argument,
-          "read past end of table when reading "
-          "DW_RLE_startx_length encoding at offset 0x%" PRIx64,
-          PreviousOffset);
+    Value0 = Data.getULEB128(C);
+    Value1 = Data.getULEB128(C);
     break;
   }
   case dwarf::DW_RLE_offset_pair: {
-    uint64_t PreviousOffset = *OffsetPtr - 1;
-    Value0 = Data.getULEB128(OffsetPtr);
-    Value1 = Data.getULEB128(OffsetPtr);
-    if (End < *OffsetPtr)
-      return createStringError(errc::invalid_argument,
-                         "read past end of table when reading "
-                         "DW_RLE_offset_pair encoding at offset 0x%" PRIx64,
-                         PreviousOffset);
+    Value0 = Data.getULEB128(C);
+    Value1 = Data.getULEB128(C);
     break;
   }
   case dwarf::DW_RLE_base_address: {
-    if ((End - *OffsetPtr) < Data.getAddressSize())
-      return createStringError(errc::invalid_argument,
-                         "insufficient space remaining in table for "
-                         "DW_RLE_base_address encoding at offset 0x%" PRIx64,
-                         *OffsetPtr - 1);
-    Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
+    Value0 = Data.getRelocatedAddress(C, &SectionIndex);
     break;
   }
   case dwarf::DW_RLE_start_end: {
-    if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2))
-      return createStringError(errc::invalid_argument,
-                         "insufficient space remaining in table for "
-                         "DW_RLE_start_end encoding "
-                         "at offset 0x%" PRIx64,
-                         *OffsetPtr - 1);
-    Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
-    Value1 = Data.getRelocatedAddress(OffsetPtr);
+    Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+    Value1 = Data.getRelocatedAddress(C);
     break;
   }
   case dwarf::DW_RLE_start_length: {
-    uint64_t PreviousOffset = *OffsetPtr - 1;
-    Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
-    Value1 = Data.getULEB128(OffsetPtr);
-    if (End < *OffsetPtr)
-      return createStringError(errc::invalid_argument,
-                         "read past end of table when reading "
-                         "DW_RLE_start_length encoding at offset 0x%" PRIx64,
-                         PreviousOffset);
+    Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+    Value1 = Data.getULEB128(C);
     break;
   }
   default:
+    consumeError(C.takeError());
     return createStringError(errc::not_supported,
-                       "unknown rnglists encoding 0x%" PRIx32
-                       " at offset 0x%" PRIx64,
-                       uint32_t(Encoding), *OffsetPtr - 1);
+                             "unknown rnglists encoding 0x%" PRIx32
+                             " at offset 0x%" PRIx64,
+                             uint32_t(Encoding), Offset);
+  }
+
+  if (!C) {
+    consumeError(C.takeError());
+    return createStringError(
+        errc::invalid_argument,
+        "read past end of table when reading %s encoding at offset 0x%" PRIx64,
+        dwarf::RLEString(Encoding).data(), Offset);
   }
 
+  *OffsetPtr = C.tell();
   EntryKind = Encoding;
   return Error::success();
 }

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
index ad4d7dd57653..0abef7f8159a 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
@@ -30,7 +30,7 @@
 # CHECK-NEXT: error: .debug_rnglists table at offset 0x39 has unsupported address size 2
 # CHECK-NEXT: error: .debug_rnglists table at offset 0x45 has unsupported segment selector size 4
 # CHECK-NEXT: error: .debug_rnglists table at offset 0x51 has more offset entries (12345678) than there is space for
-# CHECK-NEXT: error: insufficient space remaining in table for DW_RLE_start_end encoding at offset 0x69
+# CHECK-NEXT: error: read past end of table when reading DW_RLE_start_end encoding at offset 0x69
 # CHECK-NEXT: error: read past end of table when reading DW_RLE_start_length encoding at offset 0x82
 # CHECK-NEXT: error: unknown rnglists encoding 0x2a at offset 0x98
 # CHECK-NEXT: error: no end of list marker detected at end of .debug_rnglists table starting at offset 0xaa


        


More information about the llvm-commits mailing list