diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -16,6 +16,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" @@ -199,12 +200,14 @@ const DWARFDebugAbbrev *Abbrev; const DWARFSection *RangeSection; uint64_t RangeSectionBase; - /// We either keep track of the location list section or its data, depending - /// on whether we are handling a split DWARF section or not. - union { - const DWARFSection *LocSection; - StringRef LocSectionData; - }; + + /// Section containing the location lists of this unit used for non-split + /// DWARF<=v4 units. + const DWARFSection *LocSection; + + /// Location table of this unit. Used for DWARF v5 and DWO units. + std::unique_ptr LocTable; + const DWARFSection &LineSection; StringRef StringSection; const DWARFSection &StringOffsetSection; @@ -275,7 +278,6 @@ DWARFContext& getContext() const { return Context; } const DWARFSection &getInfoSection() const { return InfoSection; } const DWARFSection *getLocSection() const { return LocSection; } - StringRef getLocSectionData() const { return LocSectionData; } uint64_t getOffset() const { return Header.getOffset(); } const dwarf::FormParams &getFormParams() const { return Header.getFormParams(); @@ -319,6 +321,8 @@ return DataExtractor(StringSection, false, 0); } + const DWARFLocationTable *getLocationTable() { return LocTable.get(); } + /// Extract the range list referenced by this compile unit from the /// .debug_ranges section. If the extraction is unsuccessful, an error /// is returned. Successful extraction requires that the compile unit diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -92,49 +92,35 @@ } if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { + auto LLDumpOpts = DumpOpts; + LLDumpOpts.Verbose = false; + uint64_t Offset = *FormValue.getAsSectionOffset(); uint64_t BaseAddr = 0; if (Optional BA = U->getBaseAddress()) BaseAddr = BA->Address; - auto LLDumpOpts = DumpOpts; - LLDumpOpts.Verbose = false; - - if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { - DWARFDebugLoc DebugLoc; - DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), - Obj.getAddressSize()); - - FormValue.dump(OS, DumpOpts); - OS << ": "; - if (Expected LL = - DebugLoc.parseOneLocationList(Data, &Offset)) { - LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, - U, LLDumpOpts, Indent); - } else { - OS << '\n'; - OS.indent(Indent); - OS << formatv("error extracting location list: {0}", - fmt_consume(LL.takeError())); - } + if (const DWARFLocationTable *LT = U->getLocationTable()) { + LT->dumpLocationList(&Offset, OS, BaseAddr, MRI, U, LLDumpOpts, Indent); return; } - bool UseLocLists = !U->isDWOUnit(); - auto Data = - UseLocLists - ? DWARFDataExtractor(Obj, Obj.getLoclistsSection(), - Ctx.isLittleEndian(), Obj.getAddressSize()) - : DWARFDataExtractor(U->getLocSectionData(), Ctx.isLittleEndian(), - Obj.getAddressSize()); - - if (!Data.getData().empty()) { - // Old-style location list were used in DWARF v4 (.debug_loc.dwo section). - // Modern locations list (.debug_loclists) are used starting from v5. - // Ideally we should take the version from the .debug_loclists section - // header, but using CU's version for simplicity. - DWARFDebugLoclists(Data, UseLocLists ? U->getVersion() : 4) - .dumpLocationList(&Offset, OS, BaseAddr, MRI, U, LLDumpOpts, Indent); + DWARFDebugLoc DebugLoc; + DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), + Obj.getAddressSize()); + + FormValue.dump(OS, DumpOpts); + OS << ": "; + + if (Expected LL = + DebugLoc.parseOneLocationList(Data, &Offset)) { + LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U, + LLDumpOpts, Indent); + } else { + OS << '\n'; + OS.indent(Indent); + OS << formatv("error extracting location list: {0}", + fmt_consume(LL.takeError())); } return; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -179,14 +179,22 @@ StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) { clear(); - // For split DWARF we only need to keep track of the location list section's - // data (no relocations), and if we are reading a package file, we need to - // adjust the location list data based on the index entries. if (IsDWO) { - LocSectionData = LocSection->Data; + // If we are reading a package file, we need to adjust the location list + // data based on the index entries. + StringRef Data = LocSection->Data; if (auto *IndexEntry = Header.getIndexEntry()) if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC)) - LocSectionData = LocSectionData.substr(C->Offset, C->Length); + Data = Data.substr(C->Offset, C->Length); + LocTable = std::make_unique( + DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize()), + Header.getVersion()); + } else if (Header.getVersion() >= 5) { + LocTable = std::make_unique( + DWARFDataExtractor(Context.getDWARFObj(), + Context.getDWARFObj().getLoclistsSection(), + isLittleEndian, getAddressByteSize()), + Header.getVersion()); } }