summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/BinaryFormat/Dwarf.cpp11
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp101
4 files changed, 98 insertions, 28 deletions
diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index bea3df8074e..e345b3acabd 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -444,6 +444,17 @@ unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
.Default(DW_MACINFO_invalid);
}
+StringRef llvm::dwarf::RangeListEncodingString(unsigned Encoding) {
+ switch (Encoding) {
+ default:
+ return StringRef();
+#define HANDLE_DW_RLE(ID, NAME) \
+ case DW_RLE_##NAME: \
+ return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ }
+}
+
StringRef llvm::dwarf::CallFrameString(unsigned Encoding) {
switch (Encoding) {
default:
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index 058d3192b90..86c8d19c02f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -14,10 +14,13 @@
using namespace llvm;
-void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize) const {
+void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
+ DIDumpOptions DumpOpts) const {
- OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
- << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2, HighPC);
+ OS << (DumpOpts.DisplayRawContents ? " " : "[");
+ OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
+ << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC);
+ OS << (DumpOpts.DisplayRawContents ? "" : ")");
}
raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 2b1c91ee7b0..3a974dddc4e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -509,8 +509,9 @@ void DWARFContext::dump(
if (Length == 0)
break;
Offset = TableOffset + Length;
- } else
- Rnglists.dump(OS);
+ } else {
+ Rnglists.dump(OS, DumpOpts);
+ }
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 802fb7ecaea..c2b8b8a5e47 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -33,7 +33,7 @@ static Error createError(char const *Fmt, const Ts &... Vals) {
Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
uint32_t *OffsetPtr) {
clear();
- uint32_t TableOffset = *OffsetPtr;
+ HeaderOffset = *OffsetPtr;
// Read and verify the length field.
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
@@ -42,17 +42,21 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
*OffsetPtr);
// TODO: Add support for DWARF64.
HeaderData.Length = Data.getU32(OffsetPtr);
+ if (HeaderData.Length == 0xffffffffu)
+ return createError(
+ "DWARF64 is not supported in .debug_rnglists at offset 0x%" PRIx32,
+ HeaderOffset);
if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
return createError(".debug_rnglists table at offset 0x%" PRIx32
" has too small length (0x%" PRIx32
") to contain a complete header",
- TableOffset, length());
- uint32_t End = TableOffset + length();
- if (!Data.isValidOffsetForDataOfSize(TableOffset, End - TableOffset))
+ HeaderOffset, length());
+ uint32_t End = HeaderOffset + length();
+ if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
return createError(
"section is not large enough to contain a .debug_rnglists table "
"of length 0x%" PRIx32 " at offset 0x%" PRIx32,
- length(), TableOffset);
+ length(), HeaderOffset);
HeaderData.Version = Data.getU16(OffsetPtr);
HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -63,32 +67,37 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
if (HeaderData.Version != 5)
return createError("unrecognised .debug_rnglists table version %" PRIu16
" in table at offset 0x%" PRIx32,
- HeaderData.Version, TableOffset);
+ HeaderData.Version, HeaderOffset);
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
return createError(".debug_rnglists table at offset 0x%" PRIx32
" has unsupported address size %hhu",
- TableOffset, HeaderData.AddrSize);
+ HeaderOffset, HeaderData.AddrSize);
if (HeaderData.SegSize != 0)
return createError(".debug_rnglists table at offset 0x%" PRIx32
" has unsupported segment selector size %" PRIu8,
- TableOffset, HeaderData.SegSize);
- if (End < TableOffset + sizeof(HeaderData) +
+ HeaderOffset, HeaderData.SegSize);
+ if (End < HeaderOffset + sizeof(HeaderData) +
HeaderData.OffsetEntryCount * sizeof(uint32_t))
return createError(".debug_rnglists table at offset 0x%" PRIx32
" has more offset entries (%" PRIu32
") than there is space for",
- TableOffset, HeaderData.OffsetEntryCount);
+ HeaderOffset, HeaderData.OffsetEntryCount);
Data.setAddressSize(HeaderData.AddrSize);
for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
Offsets.push_back(Data.getU32(OffsetPtr));
- DWARFAddressRangesVector CurrentRanges;
+ DWARFRangeList CurrentRanges;
while (*OffsetPtr < End) {
+ uint32_t EntryOffset = *OffsetPtr;
uint8_t Encoding = Data.getU8(OffsetPtr);
+ MaxEncodingStringLength =
+ std::max(MaxEncodingStringLength,
+ (uint8_t)dwarf::RangeListEncodingString(Encoding).size());
switch (Encoding) {
case dwarf::DW_RLE_end_of_list:
+ CurrentRanges.push_back(RangeListEntry{EntryOffset, Encoding});
Ranges.insert(Ranges.end(), CurrentRanges);
CurrentRanges.clear();
break;
@@ -121,7 +130,8 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
*OffsetPtr - 1);
uint64_t Start = Data.getAddress(OffsetPtr);
uint64_t End = Data.getAddress(OffsetPtr);
- CurrentRanges.emplace_back(Start, End);
+ CurrentRanges.push_back(
+ RangeListEntry{EntryOffset, Encoding, Start, End});
break;
}
case dwarf::DW_RLE_start_length: {
@@ -132,7 +142,8 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
return createError("read past end of table when reading "
"DW_RLE_start_length encoding at offset 0x%" PRIx32,
PreviousOffset);
- CurrentRanges.emplace_back(Start, Start + Length);
+ CurrentRanges.push_back(
+ RangeListEntry{EntryOffset, Encoding, Start, Length});
break;
}
default:
@@ -155,12 +166,55 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
return createError(
"no end of list marker detected at end of .debug_rnglists table "
"starting at offset 0x%" PRIx32,
- TableOffset);
+ HeaderOffset);
return Error::success();
}
-void DWARFDebugRnglists::dump(raw_ostream &OS) const {
- // TODO: Add verbose printing of the raw encodings.
+static void dumpRangeEntry(raw_ostream &OS,
+ DWARFDebugRnglists::RangeListEntry Entry,
+ uint8_t AddrSize, uint8_t MaxEncodingStringLength,
+ DIDumpOptions DumpOpts) {
+ if (DumpOpts.Verbose) {
+ // Print the section offset in verbose mode.
+ OS << format("0x%8.8" PRIx32 ":", Entry.Offset);
+ auto EncodingString = dwarf::RangeListEncodingString(Entry.EntryKind);
+ // Unsupported encodings should have been reported during parsing.
+ assert(!EncodingString.empty() && "Unknown range entry encoding");
+ OS << format(" [%s%*c", EncodingString.data(),
+ MaxEncodingStringLength - EncodingString.size() + 1, ']');
+ if (Entry.EntryKind != dwarf::DW_RLE_end_of_list)
+ OS << ": ";
+ }
+
+ switch (Entry.EntryKind) {
+ case dwarf::DW_RLE_end_of_list:
+ OS << (DumpOpts.Verbose ? "" : "<End of list>");
+ break;
+ case dwarf::DW_RLE_start_length:
+ if (DumpOpts.Verbose) {
+ // Make the address range display its contents in raw form rather than
+ // as an interval (i.e. without brackets).
+ DumpOpts.DisplayRawContents = true;
+ DWARFAddressRange(Entry.Value0, Entry.Value1)
+ .dump(OS, AddrSize, DumpOpts);
+ OS << " => ";
+ }
+ DumpOpts.DisplayRawContents = false;
+ DWARFAddressRange(Entry.Value0, Entry.Value0 + Entry.Value1)
+ .dump(OS, AddrSize, DumpOpts);
+ break;
+ case dwarf::DW_RLE_start_end:
+ DWARFAddressRange(Entry.Value0, Entry.Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ default:
+ llvm_unreachable("Unsupported range list encoding");
+ }
+ OS << "\n";
+}
+
+void DWARFDebugRnglists::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+ if (DumpOpts.Verbose)
+ OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
OS << format("Range List Header: length = 0x%8.8" PRIx32
", version = 0x%4.4" PRIx16 ", "
"addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
@@ -171,19 +225,20 @@ void DWARFDebugRnglists::dump(raw_ostream &OS) const {
if (HeaderData.OffsetEntryCount > 0) {
OS << "Offsets: [";
- for (const auto &Off : Offsets)
+ for (const auto &Off : Offsets) {
OS << format("\n0x%8.8" PRIx32, Off);
+ if (DumpOpts.Verbose)
+ OS << format(" => 0x%8.8" PRIx32,
+ Off + HeaderOffset + sizeof(HeaderData));
+ }
OS << "\n]\n";
}
OS << "Ranges:\n";
- const uint32_t HexWidth = HeaderData.AddrSize * 2;
- for (const auto &List : Ranges) {
+ for (const auto &List : Ranges)
for (const auto &Entry : List)
- OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 ")\n", HexWidth, HexWidth,
- Entry.LowPC, HexWidth, HexWidth, Entry.HighPC);
- OS << "<End of list>\n";
- }
+ dumpRangeEntry(OS, Entry, HeaderData.AddrSize, MaxEncodingStringLength,
+ DumpOpts);
}
uint32_t DWARFDebugRnglists::length() const {
OpenPOWER on IntegriCloud