summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h9
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp22
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp80
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp2
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s27
6 files changed, 123 insertions, 31 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index 0615bbf0308..5cc8d789e59 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -10,6 +10,7 @@
#ifndef LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
#define LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
+#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
@@ -23,6 +24,7 @@ namespace llvm {
class Error;
class raw_ostream;
+class DWARFUnit;
/// A class representing a single range list entry.
struct RangeListEntry : public DWARFListEntryBase {
@@ -35,7 +37,9 @@ struct RangeListEntry : public DWARFListEntryBase {
Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr);
void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
- uint64_t &CurrentBase, DIDumpOptions DumpOpts) const;
+ uint64_t &CurrentBase, DIDumpOptions DumpOpts,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress) const;
bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }
};
@@ -44,7 +48,8 @@ class DWARFDebugRnglist : public DWARFListType<RangeListEntry> {
public:
/// Build a DWARFAddressRangesVector from a rangelist.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
+ getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
+ DWARFUnit &U) const;
};
class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index 8cf9e400892..8c15d9d58d4 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -156,7 +156,10 @@ public:
uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); }
uint8_t getAddrSize() const { return Header.getAddrSize(); }
- void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
+ void dump(raw_ostream &OS,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts = {}) const;
/// Return the contents of the offset entry designated by a given index.
Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
@@ -229,8 +232,11 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
}
template <typename DWARFListType>
-void DWARFListTableBase<DWARFListType>::dump(raw_ostream &OS,
- DIDumpOptions DumpOpts) const {
+void DWARFListTableBase<DWARFListType>::dump(
+ raw_ostream &OS,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) const {
Header.dump(OS, DumpOpts);
OS << HeaderString << "\n";
@@ -249,7 +255,7 @@ void DWARFListTableBase<DWARFListType>::dump(raw_ostream &OS,
for (const auto &List : ListMap)
for (const auto &Entry : List.second.getEntries())
Entry.dump(OS, getAddrSize(), MaxEncodingStringLength, CurrentBase,
- DumpOpts);
+ DumpOpts, LookupPooledAddress);
}
template <typename DWARFListType>
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index ddabc7a4652..18ec8476e9d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -269,9 +269,11 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
}
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
-static void dumpRnglistsSection(raw_ostream &OS,
- DWARFDataExtractor &rnglistData,
- DIDumpOptions DumpOpts) {
+static void
+dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) {
uint32_t Offset = 0;
while (rnglistData.isValidOffset(Offset)) {
llvm::DWARFDebugRnglistTable Rnglists;
@@ -285,7 +287,7 @@ static void dumpRnglistsSection(raw_ostream &OS,
break;
Offset = TableOffset + Length;
} else {
- Rnglists.dump(OS, DumpOpts);
+ Rnglists.dump(OS, LookupPooledAddress, DumpOpts);
}
}
}
@@ -495,18 +497,26 @@ void DWARFContext::dump(
}
}
+ auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
+ const auto &CUs = compile_units();
+ auto I = CUs.begin();
+ if (I == CUs.end())
+ return None;
+ return (*I)->getAddrOffsetSectionItem(Index);
+ };
+
if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
DObj->getRnglistsSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
DObj->getRnglistsDWOSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 72f84159957..cb5fb0d49da 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -32,21 +32,34 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
Value0 = Value1 = 0;
break;
// TODO: Support other encodings.
- case dwarf::DW_RLE_base_addressx:
- return createStringError(errc::not_supported,
- "unsupported rnglists encoding DW_RLE_base_addressx "
- "at offset 0x%" PRIx32,
- *OffsetPtr - 1);
+ case dwarf::DW_RLE_base_addressx: {
+ uint32_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%" PRIx32,
+ PreviousOffset);
+ break;
+ }
case dwarf::DW_RLE_startx_endx:
return createStringError(errc::not_supported,
"unsupported rnglists encoding DW_RLE_startx_endx at "
"offset 0x%" PRIx32,
*OffsetPtr - 1);
- case dwarf::DW_RLE_startx_length:
- return createStringError(errc::not_supported,
- "unsupported rnglists encoding DW_RLE_startx_length "
- "at offset 0x%" PRIx32,
- *OffsetPtr - 1);
+ case dwarf::DW_RLE_startx_length: {
+ uint32_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%" PRIx32,
+ PreviousOffset);
+ break;
+ }
case dwarf::DW_RLE_offset_pair: {
uint32_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getULEB128(OffsetPtr);
@@ -100,12 +113,19 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
return Error::success();
}
-DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- llvm::Optional<SectionedAddress> BaseAddr) const {
+DWARFAddressRangesVector
+DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
+ DWARFUnit &U) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
break;
+ if (RLE.EntryKind == dwarf::DW_RLE_base_addressx) {
+ BaseAddr = U.getAddrOffsetSectionItem(RLE.Value0);
+ if (!BaseAddr)
+ BaseAddr = {RLE.Value0, 0};
+ continue;
+ }
if (RLE.EntryKind == dwarf::DW_RLE_base_address) {
BaseAddr = {RLE.Value0, RLE.SectionIndex};
continue;
@@ -133,6 +153,15 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.LowPC = RLE.Value0;
E.HighPC = E.LowPC + RLE.Value1;
break;
+ case dwarf::DW_RLE_startx_length: {
+ auto Start = U.getAddrOffsetSectionItem(RLE.Value0);
+ if (!Start)
+ Start = {0, 0};
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = E.LowPC + RLE.Value1;
+ break;
+ }
default:
// Unsupported encodings should have been reported during extraction,
// so we should not run into any here.
@@ -143,9 +172,11 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
return Res;
}
-void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
- uint8_t MaxEncodingStringLength,
- uint64_t &CurrentBase, DIDumpOptions DumpOpts) const {
+void RangeListEntry::dump(
+ raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
+ uint64_t &CurrentBase, DIDumpOptions DumpOpts,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress) const {
auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
uint8_t AddrSize, DIDumpOptions DumpOpts) {
if (DumpOpts.Verbose) {
@@ -172,6 +203,17 @@ void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
case dwarf::DW_RLE_end_of_list:
OS << (DumpOpts.Verbose ? "" : "<End of list>");
break;
+ // case dwarf::DW_RLE_base_addressx:
+ case dwarf::DW_RLE_base_addressx: {
+ if (auto SA = LookupPooledAddress(Value0))
+ CurrentBase = SA->Address;
+ else
+ CurrentBase = Value0;
+ if (!DumpOpts.Verbose)
+ return;
+ OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ break;
+ }
case dwarf::DW_RLE_base_address:
// In non-verbose mode we do not print anything for this entry.
CurrentBase = Value0;
@@ -191,6 +233,14 @@ void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
case dwarf::DW_RLE_start_end:
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
break;
+ case dwarf::DW_RLE_startx_length: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ } break;
default:
llvm_unreachable("Unsupported range list encoding");
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 081163ba61f..4cf1f938c3e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -539,7 +539,7 @@ DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
isLittleEndian, RngListTable->getAddrSize());
auto RangeListOrError = RngListTable->findList(RangesData, Offset);
if (RangeListOrError)
- return RangeListOrError.get().getAbsoluteRanges(getBaseAddress());
+ return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
return RangeListOrError.takeError();
}
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
index 8f718b699f5..60533ca2721 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
@@ -57,6 +57,29 @@
# BOTH: ranges:
# BOTH-NOT: [
+# TERSE-NEXT: range list header: length = 0x0000000b, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
+# VERBOSE-SAME: range list header: length = 0x0000000b, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# BOTH-NEXT: ranges:
+# TERSE-NEXT: <End of list>
+
+# VERBOSE-NEXT: 0x00000082: [DW_RLE_base_addressx]: 0x0000000000000000
+# VERBOSE-NEXT: 0x00000084: [DW_RLE_end_of_list ]
+
+# TERSE-NEXT: range list header: length = 0x0000000c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
+# VERBOSE-SAME: range list header: length = 0x0000000c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# BOTH-NEXT: ranges:
+# TERSE-NEXT: [0x0000000000000000, 0x000000000000002a)
+# TERSE-NEXT: <End of list>
+
+# VERBOSE-NEXT: 0x000000a1: [DW_RLE_startx_length]: 0x0000000000000002, 0x000000000000002a => [0x0000000000000000, 0x000000000000002a)
+# VERBOSE-NEXT: 0x000000a4: [DW_RLE_end_of_list ]
+
# TERSE-NEXT: range list header: length = 0x0000000e, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
@@ -87,9 +110,7 @@
# BOTH-NOT: range list header:
# ERR-NOT: error:
-# ERR: error: unsupported rnglists encoding DW_RLE_base_addressx at offset 0x82
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_endx at offset 0x91
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_length at offset 0xa1
+# ERR: error: unsupported rnglists encoding DW_RLE_startx_endx at offset 0x91
# ERR-NOT: error:
.section .debug_rnglists,"",@progbits
OpenPOWER on IntegriCloud