diff options
| author | George Rimar <grimar@accesssoftek.com> | 2018-10-22 11:30:54 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2018-10-22 11:30:54 +0000 |
| commit | 4c7dd9cf0ad5d4de0281205c3e1017d21dbb6ba1 (patch) | |
| tree | 719ad1ae6ab2a3cb7da279518aea4669494ae8a8 /llvm/lib | |
| parent | 674581afbbd180745474adf0dcfebfd97e62dde7 (diff) | |
| download | bcm5719-llvm-4c7dd9cf0ad5d4de0281205c3e1017d21dbb6ba1.tar.gz bcm5719-llvm-4c7dd9cf0ad5d4de0281205c3e1017d21dbb6ba1.zip | |
[llvm-dwarfdump] - Add the support of parsing .debug_loclists.
This teaches llvm-dwarfdump to dump the content of .debug_loclists sections.
It converts the DWARFDebugLocDWO class to DWARFDebugLoclists,
teaches llvm-dwarfdump about .debug_loclists section and
adds the implementation for parsing the DW_LLE_offset_pair entries.
Differential revision: https://reviews.llvm.org/D53364
llvm-svn: 344895
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 36 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 78 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 22 |
3 files changed, 108 insertions, 28 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 18ec8476e9d..1f3753809a2 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -292,6 +292,27 @@ dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, } } +static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, + DWARFDataExtractor Data, + const MCRegisterInfo *MRI, + Optional<uint64_t> DumpOffset) { + uint32_t Offset = 0; + DWARFDebugLoclists Loclists; + + DWARFListTableHeader Header(".debug_loclists", "locations"); + if (Error E = Header.extract(Data, &Offset)) { + WithColor::error() << toString(std::move(E)) << '\n'; + return; + } + + Header.dump(OS, DumpOpts); + DataExtractor LocData(Data.getData().drop_front(Offset), + Data.isLittleEndian(), Header.getAddrSize()); + + Loclists.parse(LocData); + Loclists.dump(OS, 0, MRI, DumpOffset); +} + void DWARFContext::dump( raw_ostream &OS, DIDumpOptions DumpOpts, std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { @@ -366,9 +387,15 @@ void DWARFContext::dump( DObj->getLocSection().Data)) { getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset); } + if (shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, + DObj->getLoclistsSection().Data)) { + DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), + 0); + dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), DumpOffset); + } if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, DObj->getLocDWOSection().Data)) { - getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset); + getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOffset); } if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, @@ -696,11 +723,11 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() { return Loc.get(); } -const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() { +const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() { if (LocDWO) return LocDWO.get(); - LocDWO.reset(new DWARFDebugLocDWO()); + LocDWO.reset(new DWARFDebugLoclists()); // Assume all compile units have the same address byte size. // FIXME: We don't need AddressSize for split DWARF since relocatable // addresses cannot appear there. At the moment DWARFExpression requires it. @@ -1213,6 +1240,7 @@ class DWARFObjInMemory final : public DWARFObject { DWARFSectionMap InfoSection; DWARFSectionMap LocSection; + DWARFSectionMap LocListsSection; DWARFSectionMap LineSection; DWARFSectionMap RangeSection; DWARFSectionMap RnglistsSection; @@ -1234,6 +1262,7 @@ class DWARFObjInMemory final : public DWARFObject { return StringSwitch<DWARFSectionMap *>(Name) .Case("debug_info", &InfoSection) .Case("debug_loc", &LocSection) + .Case("debug_loclists", &LocListsSection) .Case("debug_line", &LineSection) .Case("debug_str_offsets", &StringOffsetSection) .Case("debug_ranges", &RangeSection) @@ -1529,6 +1558,7 @@ public: StringRef getAbbrevSection() const override { return AbbrevSection; } const DWARFSection &getLocSection() const override { return LocSection; } + const DWARFSection &getLoclistsSection() const override { return LocListsSection; } StringRef getARangeSection() const override { return ARangeSection; } StringRef getDebugFrameSection() const override { return DebugFrameSection; } StringRef getEHFrameSection() const override { return EHFrameSection; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index 617b914ecce..bfcf799d230 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -144,24 +144,39 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) { WithColor::error() << "failed to consume entire .debug_loc section\n"; } -Optional<DWARFDebugLocDWO::LocationList> -DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) { +Optional<DWARFDebugLoclists::LocationList> +DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset) { LocationList LL; LL.Offset = *Offset; // dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list. while (auto Kind = static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) { - if (Kind != dwarf::DW_LLE_startx_length) { + + Entry E; + E.Kind = Kind; + switch (Kind) { + case dwarf::DW_LLE_startx_length: + E.Value0 = Data.getULEB128(Offset); + E.Value1 = Data.getU32(Offset); + break; + case dwarf::DW_LLE_start_length: + E.Value0 = Data.getAddress(Offset); + E.Value1 = Data.getULEB128(Offset); + break; + case dwarf::DW_LLE_offset_pair: + E.Value0 = Data.getULEB128(Offset); + E.Value1 = Data.getULEB128(Offset); + break; + case dwarf::DW_LLE_base_address: + E.Value0 = Data.getAddress(Offset); + break; + default: WithColor::error() << "dumping support for LLE of kind " << (int)Kind << " not implemented\n"; return None; } - Entry E; - E.Start = Data.getULEB128(Offset); - E.Length = Data.getU32(Offset); - unsigned Bytes = Data.getU16(Offset); // A single location description describing the location of the object... StringRef str = Data.getData().substr(*Offset, Bytes); @@ -174,7 +189,7 @@ DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) { return LL; } -void DWARFDebugLocDWO::parse(DataExtractor data) { +void DWARFDebugLoclists::parse(DataExtractor data) { IsLittleEndian = data.isLittleEndian(); AddressSize = data.getAddressSize(); @@ -187,8 +202,8 @@ void DWARFDebugLocDWO::parse(DataExtractor data) { } } -DWARFDebugLocDWO::LocationList const * -DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const { +DWARFDebugLoclists::LocationList const * +DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const { auto It = std::lower_bound( Locations.begin(), Locations.end(), Offset, [](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; }); @@ -197,23 +212,46 @@ DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const { return nullptr; } -void DWARFDebugLocDWO::LocationList::dump(raw_ostream &OS, bool IsLittleEndian, - unsigned AddressSize, - const MCRegisterInfo *MRI, - unsigned Indent) const { +void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr, + bool IsLittleEndian, + unsigned AddressSize, + const MCRegisterInfo *MRI, + unsigned Indent) const { for (const Entry &E : Entries) { - OS << '\n'; - OS.indent(Indent); - OS << "Addr idx " << E.Start << " (w/ length " << E.Length << "): "; + switch (E.Kind) { + case dwarf::DW_LLE_startx_length: + OS << '\n'; + OS.indent(Indent); + OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): "; + break; + case dwarf::DW_LLE_start_length: + OS << '\n'; + OS.indent(Indent); + OS << format("[0x%8.8x, 0x%8.8x): ", E.Value0, E.Value0 + E.Value1); + break; + case dwarf::DW_LLE_offset_pair: + OS << '\n'; + OS.indent(Indent); + OS << format("[0x%8.8x, 0x%8.8x): ", BaseAddr + E.Value0, + BaseAddr + E.Value1); + break; + case dwarf::DW_LLE_base_address: + BaseAddr = E.Value0; + break; + default: + llvm_unreachable("unreachable locations list kind"); + } + dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI); } } -void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - Optional<uint64_t> Offset) const { +void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr, + const MCRegisterInfo *MRI, + Optional<uint64_t> Offset) const { auto DumpLocationList = [&](const LocationList &L) { OS << format("0x%8.8x: ", L.Offset); - L.dump(OS, IsLittleEndian, AddressSize, MRI, /*Indent=*/12); + L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, /*Indent=*/12); OS << "\n\n"; }; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index b4413653290..76430b41f18 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -102,7 +102,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, FormValue.dump(OS, DumpOpts); if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { uint32_t Offset = *FormValue.getAsSectionOffset(); - if (!U->isDWOUnit()) { + if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { DWARFDebugLoc DebugLoc; DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), Obj.getAddressSize()); @@ -115,11 +115,23 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, Indent); } else OS << "error extracting location list."; - } else { - DataExtractor Data(U->getLocSectionData(), Ctx.isLittleEndian(), 0); - auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset); + return; + } + + StringRef LoclistsSectionData = + U->isDWOUnit() ? U->getLocSectionData() : Obj.getLoclistsSection().Data; + if (!LoclistsSectionData.empty()) { + DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(), + Obj.getAddressSize()); + auto LL = DWARFDebugLoclists::parseOneLocationList(Data, &Offset); + + uint64_t BaseAddr = 0; + if (Optional<SectionedAddress> BA = U->getBaseAddress()) + BaseAddr = BA->Address; + if (LL) - LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent); + LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, + Indent); else OS << "error extracting location list."; } |

