diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 55 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 13 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 3 |
5 files changed, 78 insertions, 26 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 84444ca5174..551e8a2751b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1158,11 +1158,12 @@ void DwarfDebug::finalizeModuleInfo() { if (U.hasRangeLists()) U.addRnglistsBase(); - if (!DebugLocs.getLists().empty() && !useSplitDwarf()) { + if (!DebugLocs.getLists().empty()) { DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base")); - U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base, - DebugLocs.getSym(), - TLOF.getDwarfLoclistsSection()->getBeginSymbol()); + if (!useSplitDwarf()) + U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base, + DebugLocs.getSym(), + TLOF.getDwarfLoclistsSection()->getBeginSymbol()); } } @@ -1207,9 +1208,10 @@ void DwarfDebug::endModule() { emitDebugStr(); if (useSplitDwarf()) + // Handles debug_loc.dwo / debug_loclists.dwo section emission emitDebugLocDWO(); else - // Emit info into a debug loc section. + // Handles debug_loc / debug_loclists section emission emitDebugLoc(); // Corresponding abbreviations into a abbrev section. @@ -2335,8 +2337,6 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm, const auto &DebugLocs = DD.getDebugLocs(); - // FIXME: Generate the offsets table and use DW_FORM_loclistx with the - // DW_AT_loclists_base attribute. Until then set the number of offsets to 0. Asm->OutStreamer->AddComment("Offset entry count"); Asm->emitInt32(DebugLocs.getLists().size()); Asm->OutStreamer->EmitLabel(DebugLocs.getSym()); @@ -2443,27 +2443,29 @@ static void emitRangeList( } } +// Handles emission of both debug_loclist / debug_loclist.dwo static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List) { - emitRangeList( - DD, Asm, List.Label, DD.getDebugLocs().getEntries(List), *List.CU, - dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair, - dwarf::DW_LLE_startx_length, dwarf::DW_LLE_end_of_list, - llvm::dwarf::LocListEncodingString, - /* ShouldUseBaseAddress */ true, - [&](const DebugLocStream::Entry &E) { - DD.emitDebugLocEntryLocation(E, List.CU); - }); + emitRangeList(DD, Asm, List.Label, DD.getDebugLocs().getEntries(List), + *List.CU, dwarf::DW_LLE_base_addressx, + dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length, + dwarf::DW_LLE_end_of_list, llvm::dwarf::LocListEncodingString, + /* ShouldUseBaseAddress */ true, + [&](const DebugLocStream::Entry &E) { + DD.emitDebugLocEntryLocation(E, List.CU); + }); } -// Emit locations into the .debug_loc/.debug_rnglists section. +// Emit locations into the .debug_loc/.debug_loclists section. void DwarfDebug::emitDebugLoc() { if (DebugLocs.getLists().empty()) return; MCSymbol *TableEnd = nullptr; if (getDwarfVersion() >= 5) { + Asm->OutStreamer->SwitchSection( Asm->getObjFileLowering().getDwarfLoclistsSection()); + TableEnd = emitLoclistsTableHeader(Asm, *this); } else { Asm->OutStreamer->SwitchSection( @@ -2477,11 +2479,29 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer->EmitLabel(TableEnd); } +// Emit locations into the .debug_loc.dwo/.debug_loclists.dwo section. void DwarfDebug::emitDebugLocDWO() { + if (DebugLocs.getLists().empty()) + return; + + if (getDwarfVersion() >= 5) { + MCSymbol *TableEnd = nullptr; + Asm->OutStreamer->SwitchSection( + Asm->getObjFileLowering().getDwarfLoclistsDWOSection()); + TableEnd = emitLoclistsTableHeader(Asm, *this); + for (const auto &List : DebugLocs.getLists()) + emitLocList(*this, Asm, List); + + if (TableEnd) + Asm->OutStreamer->EmitLabel(TableEnd); + return; + } + for (const auto &List : DebugLocs.getLists()) { Asm->OutStreamer->SwitchSection( Asm->getObjFileLowering().getDwarfLocDWOSection()); Asm->OutStreamer->EmitLabel(List.Label); + for (const auto &Entry : DebugLocs.getEntries(List)) { // GDB only supports startx_length in pre-standard split-DWARF. // (in v5 standard loclists, it currently* /only/ supports base_address + @@ -2494,7 +2514,6 @@ void DwarfDebug::emitDebugLocDWO() { unsigned idx = AddrPool.getIndex(Entry.Begin); Asm->EmitULEB128(idx); Asm->EmitLabelDifference(Entry.End, Entry.Begin, 4); - emitDebugLocEntryLocation(Entry, List.CU); } Asm->emitInt8(dwarf::DW_LLE_end_of_list); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index f7b3fb495f9..012bab35460 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -404,6 +404,14 @@ void DWARFContext::dump( dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *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); + } + + if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, DObj->getLocDWOSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(), @@ -1385,6 +1393,7 @@ class DWARFObjInMemory final : public DWARFObject { DWARFSectionMap LocSection; DWARFSectionMap LoclistsSection; + DWARFSectionMap LoclistsDWOSection; DWARFSectionMap LineSection; DWARFSectionMap RangesSection; DWARFSectionMap RnglistsSection; @@ -1411,6 +1420,7 @@ class DWARFObjInMemory final : public DWARFObject { return StringSwitch<DWARFSectionMap *>(Name) .Case("debug_loc", &LocSection) .Case("debug_loclists", &LoclistsSection) + .Case("debug_loclists.dwo", &LoclistsDWOSection) .Case("debug_line", &LineSection) .Case("debug_frame", &FrameSection) .Case("eh_frame", &EHFrameSection) @@ -1741,6 +1751,9 @@ public: const DWARFSection &getRnglistsDWOSection() const override { return RnglistsDWOSection; } + const DWARFSection &getLoclistsDWOSection() const override { + return LoclistsDWOSection; + } const DWARFSection &getAddrSection() const override { return AddrSection; } StringRef getCUIndexSection() const override { return CUIndexSection; } StringRef getGdbIndexSection() const override { return GdbIndexSection; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 6cf30270539..cc3d021b0dd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -89,6 +89,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, if (FormValue.getForm() == DW_FORM_loclistx) { FormValue.dump(OS, DumpOpts); + if (auto LoclistOffset = U->getLoclistOffset(Offset)) Offset = *LoclistOffset + U->getLocSectionBase(); else diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index e5d33e13644..b662e88816f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -186,9 +186,16 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, if (auto *IndexEntry = Header.getIndexEntry()) if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC)) Data = Data.substr(C->Offset, C->Length); - LocTable = std::make_unique<DWARFDebugLoclists>( - DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize()), - Header.getVersion()); + + DWARFDataExtractor DWARFData = + Header.getVersion() >= 5 + ? DWARFDataExtractor(Context.getDWARFObj(), + Context.getDWARFObj().getLoclistsDWOSection(), + isLittleEndian, getAddressByteSize()) + : DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize()); + LocTable = + std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion()); + } else if (Header.getVersion() >= 5) { LocTable = std::make_unique<DWARFDebugLoclists>( DWARFDataExtractor(Context.getDWARFObj(), @@ -502,14 +509,23 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { RangeSectionBase = RngListTable->getHeaderSize(); } - // FIXME: add loclists.dwo support - setLocSection(&Context.getDWARFObj().getLoclistsSection(), - toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0)); + // In a split dwarf unit, there is no DW_AT_loclists_base attribute. + // Setting LocSectionBase to point past the table header. + if (IsDWO) + setLocSection(&Context.getDWARFObj().getLoclistsDWOSection(), + DWARFListTableHeader::getHeaderSize(Header.getFormat())); + else + setLocSection(&Context.getDWARFObj().getLoclistsSection(), + toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0)); if (LocSection->Data.size()) { - LoclistTableHeader.emplace(".debug_loclists", "locations"); - uint64_t Offset = LocSectionBase; + if (IsDWO) + LoclistTableHeader.emplace(".debug_loclists.dwo", "locations"); + else + LoclistTableHeader.emplace(".debug_loclists", "locations"); + uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat()); + uint64_t Offset = getLocSectionBase(); DWARFDataExtractor Data(Context.getDWARFObj(), *LocSection, isLittleEndian, getAddressByteSize()); if (Offset < HeaderSize) diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 53a9467041c..5b4da1998c4 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -464,6 +464,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { DwarfRnglistsDWOSection = Ctx->getELFSection(".debug_rnglists.dwo", DebugSecType, ELF::SHF_EXCLUDE); + DwarfLoclistsDWOSection = + Ctx->getELFSection(".debug_loclists.dwo", DebugSecType, ELF::SHF_EXCLUDE); + // DWP Sections DwarfCUIndexSection = Ctx->getELFSection(".debug_cu_index", DebugSecType, 0); |