aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp139
1 files changed, 74 insertions, 65 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 9ae4c5b73ebe..d12acca1962e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
@@ -16,114 +17,87 @@
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);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
+ break;
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();
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
- return getAbsoluteRanges(BaseAddr, [&](uint32_t Index) {
- return U.getAddrOffsetSectionItem(Index);
- });
+ return getAbsoluteRanges(
+ BaseAddr, U.getAddressByteSize(),
+ [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- Optional<object::SectionedAddress> BaseAddr,
+ Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const {
DWARFAddressRangesVector Res;
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
break;
@@ -146,8 +120,12 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
switch (RLE.EntryKind) {
case dwarf::DW_RLE_offset_pair:
E.LowPC = RLE.Value0;
+ if (E.LowPC == Tombstone)
+ continue;
E.HighPC = RLE.Value1;
if (BaseAddr) {
+ if (BaseAddr->Address == Tombstone)
+ continue;
E.LowPC += BaseAddr->Address;
E.HighPC += BaseAddr->Address;
}
@@ -169,11 +147,26 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.HighPC = E.LowPC + RLE.Value1;
break;
}
+ case dwarf::DW_RLE_startx_endx: {
+ auto Start = LookupPooledAddress(RLE.Value0);
+ if (!Start)
+ Start = {0, -1ULL};
+ auto End = LookupPooledAddress(RLE.Value1);
+ if (!End)
+ End = {0, -1ULL};
+ // FIXME: Some error handling if Start.SectionIndex != End.SectionIndex
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = End->Address;
+ break;
+ }
default:
// Unsupported encodings should have been reported during extraction,
// so we should not run into any here.
llvm_unreachable("Unsupported range list encoding");
}
+ if (E.LowPC == Tombstone)
+ continue;
Res.push_back(E);
}
return Res;
@@ -206,6 +199,8 @@ void RangeListEntry::dump(
OS << ": ";
}
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
+
switch (EntryKind) {
case dwarf::DW_RLE_end_of_list:
OS << (DumpOpts.Verbose ? "" : "<End of list>");
@@ -217,7 +212,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
}
case dwarf::DW_RLE_base_address:
@@ -225,7 +220,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
case dwarf::DW_RLE_start_length:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
@@ -233,8 +228,11 @@ void RangeListEntry::dump(
break;
case dwarf::DW_RLE_offset_pair:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
- .dump(OS, AddrSize, DumpOpts);
+ if (CurrentBase != Tombstone)
+ DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
+ .dump(OS, AddrSize, DumpOpts);
+ else
+ OS << "dead code";
break;
case dwarf::DW_RLE_start_end:
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
@@ -247,6 +245,17 @@ void RangeListEntry::dump(
DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
break;
}
+ case dwarf::DW_RLE_startx_endx: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ uint64_t End = 0;
+ if (auto SA = LookupPooledAddress(Value1))
+ End = SA->Address;
+ DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts);
+ break;
+ }
default:
llvm_unreachable("Unsupported range list encoding");
}