From 1fbe8a82e1ea0168ee10079a18140135222d1d2c Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 21 Nov 2019 16:16:50 +0100 Subject: [DWARF] Add support for parsing/dumping section indices in location lists Summary: This does exactly what it says on the box. The only small gotcha is the section index computation for offset_pair entries, which can use either the base address section, or the section from the offset_pair entry. This is to support both the cases where the base address is relocated (points to the base of the CU, typically), and the case where the base address is a constant (typically zero) and relocations are on the offsets themselves. Reviewers: dblaikie, JDevlieghere, aprantl, SouraVX Subscribers: hiraditya, llvm-commits, probinson Tags: #llvm Differential Revision: https://reviews.llvm.org/D70540 --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 15 +++---- llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 65 +++++++++++++++++++----------- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 3 +- 3 files changed, 51 insertions(+), 32 deletions(-) (limited to 'llvm/lib/DebugInfo') diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 9d662da31b6..b268d2e6aef 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -288,6 +288,7 @@ static void dumpRnglistsSection( static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const MCRegisterInfo *MRI, + const DWARFObject &Obj, Optional DumpOffset) { uint64_t Offset = 0; @@ -306,13 +307,13 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, if (DumpOffset) { if (DumpOffset >= Offset && DumpOffset < EndOffset) { Offset = *DumpOffset; - Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, nullptr, + Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr, DumpOpts, /*Indent=*/0); OS << "\n"; return; } } else { - Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, DumpOpts); + Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts); } Offset = EndOffset; } @@ -394,21 +395,21 @@ void DWARFContext::dump( if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, DObj->getLocSection().Data)) { - getDebugLoc()->dump(OS, getRegisterInfo(), LLDumpOpts, *Off); + getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off); } if (const auto *Off = shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, DObj->getLoclistsSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); } if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists, DObj->getLoclistsDWOSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); } if (const auto *Off = @@ -420,11 +421,11 @@ void DWARFContext::dump( if (*Off) { uint64_t Offset = **Off; Loc.dumpLocationList(&Offset, OS, - /*BaseAddr=*/None, getRegisterInfo(), nullptr, + /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr, LLDumpOpts, /*Indent=*/0); OS << "\n"; } else { - Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), + Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj, LLDumpOpts); } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index baa35eb813c..8f373e2f551 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -66,23 +66,24 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { LowPC->SectionIndex}, E.Loc}; } - case dwarf::DW_LLE_offset_pair: + case dwarf::DW_LLE_offset_pair: { if (!Base) { return createStringError( inconvertibleErrorCode(), "Unable to resolve DW_LLE_offset_pair: base address unknown"); } - return DWARFLocationExpression{DWARFAddressRange{Base->Address + E.Value0, - Base->Address + E.Value1, - Base->SectionIndex}, - E.Loc}; + DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1, + Base->SectionIndex}; + if (Range.SectionIndex == SectionedAddress::UndefSection) + Range.SectionIndex = E.SectionIndex; + return DWARFLocationExpression{Range, E.Loc}; + } case dwarf::DW_LLE_base_address: - Base = SectionedAddress{E.Value0, SectionedAddress::UndefSection}; + Base = SectionedAddress{E.Value0, E.SectionIndex}; return None; case dwarf::DW_LLE_start_length: return DWARFLocationExpression{ - DWARFAddressRange{E.Value0, E.Value0 + E.Value1, - SectionedAddress::UndefSection}, + DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex}, E.Loc}; default: llvm_unreachable("unreachable locations list kind"); @@ -104,7 +105,8 @@ static void dumpExpression(raw_ostream &OS, ArrayRef Data, bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, Optional BaseAddr, const MCRegisterInfo *MRI, - DWARFUnit *U, DIDumpOptions DumpOpts, + const DWARFObject &Obj, DWARFUnit *U, + DIDumpOptions DumpOpts, unsigned Indent) const { DWARFLocationInterpreter Interp( BaseAddr, [U](uint32_t Index) -> Optional { @@ -116,7 +118,7 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) { Expected> Loc = Interp.Interpret(E); if (!Loc || DumpOpts.DisplayRawContents) - dumpRawEntry(E, OS, Indent); + dumpRawEntry(E, OS, Indent, DumpOpts, Obj); if (Loc && *Loc) { OS << "\n"; OS.indent(Indent); @@ -125,10 +127,7 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, DIDumpOptions RangeDumpOpts(DumpOpts); RangeDumpOpts.DisplayRawContents = false; - const DWARFObject *Obj = nullptr; - if (U) - Obj = &U->getContext().getDWARFObj(); - Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, Obj); + Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj); } if (!Loc) consumeError(Loc.takeError()); @@ -167,12 +166,12 @@ Error DWARFLocationTable::visitAbsoluteLocationList( } void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - DIDumpOptions DumpOpts, + const DWARFObject &Obj, DIDumpOptions DumpOpts, Optional DumpOffset) const { auto BaseAddr = None; unsigned Indent = 12; if (DumpOffset) { - dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, nullptr, DumpOpts, + dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts, Indent); } else { uint64_t Offset = 0; @@ -182,7 +181,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, nullptr, + CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts, Indent); OS << '\n'; } @@ -194,8 +193,9 @@ Error DWARFDebugLoc::visitLocationList( function_ref Callback) const { DataExtractor::Cursor C(*Offset); while (true) { + uint64_t SectionIndex; uint64_t Value0 = Data.getRelocatedAddress(C); - uint64_t Value1 = Data.getRelocatedAddress(C); + uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex); DWARFLocationEntry E; @@ -208,10 +208,12 @@ Error DWARFDebugLoc::visitLocationList( } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) { E.Kind = dwarf::DW_LLE_base_address; E.Value0 = Value1; + E.SectionIndex = SectionIndex; } else { E.Kind = dwarf::DW_LLE_offset_pair; E.Value0 = Value0; E.Value1 = Value1; + E.SectionIndex = SectionIndex; unsigned Bytes = Data.getU16(C); // A single location description describing the location of the object... Data.getU8(C, E.Loc, Bytes); @@ -227,7 +229,9 @@ Error DWARFDebugLoc::visitLocationList( } void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry, - raw_ostream &OS, unsigned Indent) const { + raw_ostream &OS, unsigned Indent, + DIDumpOptions DumpOpts, + const DWARFObject &Obj) const { uint64_t Value0, Value1; switch (Entry.Kind) { case dwarf::DW_LLE_base_address: @@ -248,6 +252,7 @@ void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry, OS.indent(Indent); OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", " << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')'; + DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex); } Error DWARFDebugLoclists::visitLocationList( @@ -276,12 +281,13 @@ Error DWARFDebugLoclists::visitLocationList( case dwarf::DW_LLE_offset_pair: E.Value0 = Data.getULEB128(C); E.Value1 = Data.getULEB128(C); + E.SectionIndex = SectionedAddress::UndefSection; break; case dwarf::DW_LLE_base_address: - E.Value0 = Data.getRelocatedAddress(C); + E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex); break; case dwarf::DW_LLE_start_length: - E.Value0 = Data.getRelocatedAddress(C); + E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex); E.Value1 = Data.getULEB128(C); break; case dwarf::DW_LLE_startx_endx: @@ -310,7 +316,9 @@ Error DWARFDebugLoclists::visitLocationList( } void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry, - raw_ostream &OS, unsigned Indent) const { + raw_ostream &OS, unsigned Indent, + DIDumpOptions DumpOpts, + const DWARFObject &Obj) const { size_t MaxEncodingStringLength = 0; #define HANDLE_DW_LLE(ID, NAME) \ MaxEncodingStringLength = std::max(MaxEncodingStringLength, \ @@ -339,10 +347,19 @@ void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry, break; } OS << ')'; + switch (Entry.Kind) { + case dwarf::DW_LLE_start_length: + case dwarf::DW_LLE_base_address: + DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex); + break; + default: + break; + } } void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, const MCRegisterInfo *MRI, + const DWARFObject &Obj, DIDumpOptions DumpOpts) { if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) { OS << "Invalid dump range\n"; @@ -355,8 +372,8 @@ void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, nullptr, - DumpOpts, /*Indent=*/12); + CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, + nullptr, DumpOpts, /*Indent=*/12); OS << '\n'; } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index cc3d021b0dd..404bc13b178 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -96,7 +96,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, return; } U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), - MRI, U, DumpOpts, Indent); + MRI, Ctx.getDWARFObj(), U, DumpOpts, + Indent); return; } -- cgit v1.2.3