forked from OSchip/llvm-project
DebugInfo: Cleanup RLE dumping, using a length-constrained DataExtractor rather than carrying the end offset separately
This commit is contained in:
parent
528a1f121c
commit
ad68a8b952
|
@ -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
|
||||
|
|
|
@ -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)>
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue