[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