diff options
| author | David Blaikie <dblaikie@gmail.com> | 2018-10-20 06:16:25 +0000 |
|---|---|---|
| committer | David Blaikie <dblaikie@gmail.com> | 2018-10-20 06:16:25 +0000 |
| commit | 59ac20643335b69c8023fc62a95d5b59a73e604a (patch) | |
| tree | 5389178ad14b5bbe5e68dc19378490316a245ad5 /llvm/lib/DebugInfo | |
| parent | 161dd3c186e480a4fd4ef8af395f5b0845ec9d5f (diff) | |
| download | bcm5719-llvm-59ac20643335b69c8023fc62a95d5b59a73e604a.tar.gz bcm5719-llvm-59ac20643335b69c8023fc62a95d5b59a73e604a.zip | |
llvm-dwarfdump: Support RLE_addressx and RLE_startx_length in .debug_rnglists
llvm-svn: 344835
Diffstat (limited to 'llvm/lib/DebugInfo')
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp | 80 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 2 |
3 files changed, 82 insertions, 22 deletions
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(); } |

