diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 623 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 39 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 2 |
6 files changed, 443 insertions, 265 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 495e09fbae3..c91bd27c91a 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -60,9 +60,10 @@ using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; static void dumpAccelSection(raw_ostream &OS, StringRef Name, - const DWARFSection& Section, StringRef StringSection, - bool LittleEndian) { - DWARFDataExtractor AccelSection(Section, LittleEndian, 0); + const DWARFObject &Obj, + const DWARFSection &Section, + StringRef StringSection, bool LittleEndian) { + DWARFDataExtractor AccelSection(Obj, Section, LittleEndian, 0); DataExtractor StrData(StringSection, LittleEndian, 0); OS << "\n." << Name << " contents:\n"; DWARFAcceleratorTable Accel(AccelSection, StrData); @@ -73,9 +74,10 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name, static void dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName, + const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, bool LittleEndian) { - DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0); + DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); uint32_t Offset = 0; uint64_t SectionSize = StringOffsetsSection.Data.size(); @@ -153,6 +155,7 @@ dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName, // monolithic series of string offsets, as generated by the pre-DWARF v5 // implementation of split DWARF. static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, + const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, bool LittleEndian, unsigned MaxVersion) { @@ -163,7 +166,7 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, // we assume that the section is formatted like a DWARF v5 string offsets // section. if (MaxVersion >= 5) - dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection, + dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection, StringSection, LittleEndian); else { DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0); @@ -259,7 +262,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { uint32_t offset = 0; if (DumpType == DIDT_All || DumpType == DIDT_Aranges) { OS << "\n.debug_aranges contents:\n"; - DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); + DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0); DWARFDebugArangeSet set; while (set.extract(arangesData, &offset)) set.dump(OS); @@ -274,8 +277,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { if (!CUDIE) continue; if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) { - DWARFDataExtractor lineData(getLineSection(), isLittleEndian(), - savedAddressByteSize); + DWARFDataExtractor lineData(*DObj, DObj->getLineSection(), + isLittleEndian(), savedAddressByteSize); DWARFDebugLine::LineTable LineTable; uint32_t Offset = *StmtOffset; LineTable.parse(lineData, &Offset); @@ -297,8 +300,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) { OS << "\n.debug_line.dwo contents:\n"; unsigned stmtOffset = 0; - DWARFDataExtractor lineData(getLineDWOSection(), isLittleEndian(), - savedAddressByteSize); + DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(), + isLittleEndian(), savedAddressByteSize); DWARFDebugLine::LineTable LineTable; while (LineTable.Prologue.parse(lineData, &stmtOffset)) { LineTable.dump(OS); @@ -308,7 +311,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { if (DumpType == DIDT_All || DumpType == DIDT_Str) { OS << "\n.debug_str contents:\n"; - DataExtractor strData(getStringSection(), isLittleEndian(), 0); + DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0); offset = 0; uint32_t strOffset = 0; while (const char *s = strData.getCStr(&offset)) { @@ -318,9 +321,9 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { } if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) && - !getStringDWOSection().empty()) { + !DObj->getStringDWOSection().empty()) { OS << "\n.debug_str.dwo contents:\n"; - DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0); + DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0); offset = 0; uint32_t strDWOOffset = 0; while (const char *s = strDWOData.getCStr(&offset)) { @@ -335,8 +338,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { // sizes, but for simplicity we just use the address byte size of the last // compile unit (there is no easy and fast way to associate address range // list and the compile unit it describes). - DWARFDataExtractor rangesData(getRangeSection(), isLittleEndian(), - savedAddressByteSize); + DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(), + isLittleEndian(), savedAddressByteSize); offset = 0; DWARFDebugRangeList rangeList; while (rangeList.extract(rangesData, &offset)) @@ -344,55 +347,56 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { } if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) - DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false) + DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false) .dump("debug_pubnames", OS); if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes) - DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false) + DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false) .dump("debug_pubtypes", OS); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames) - DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(), + DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(), true /* GnuStyle */) .dump("debug_gnu_pubnames", OS); if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes) - DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(), + DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(), true /* GnuStyle */) .dump("debug_gnu_pubtypes", OS); if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets) - dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(), - getStringSection(), isLittleEndian(), - getMaxVersion()); + dumpStringOffsetsSection( + OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(), + DObj->getStringSection(), isLittleEndian(), getMaxVersion()); if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) { - dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", - getStringOffsetDWOSection(), getStringDWOSection(), - isLittleEndian(), getMaxVersion()); + dumpStringOffsetsSection( + OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(), + DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion()); } if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) && - !getGdbIndexSection().empty()) { + !DObj->getGdbIndexSection().empty()) { OS << "\n.gnu_index contents:\n"; getGdbIndex().dump(OS); } if (DumpType == DIDT_All || DumpType == DIDT_AppleNames) - dumpAccelSection(OS, "apple_names", getAppleNamesSection(), - getStringSection(), isLittleEndian()); + dumpAccelSection(OS, "apple_names", *DObj, DObj->getAppleNamesSection(), + DObj->getStringSection(), isLittleEndian()); if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes) - dumpAccelSection(OS, "apple_types", getAppleTypesSection(), - getStringSection(), isLittleEndian()); + dumpAccelSection(OS, "apple_types", *DObj, DObj->getAppleTypesSection(), + DObj->getStringSection(), isLittleEndian()); if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces) - dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(), - getStringSection(), isLittleEndian()); + dumpAccelSection(OS, "apple_namespaces", *DObj, + DObj->getAppleNamespacesSection(), + DObj->getStringSection(), isLittleEndian()); if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC) - dumpAccelSection(OS, "apple_objc", getAppleObjCSection(), - getStringSection(), isLittleEndian()); + dumpAccelSection(OS, "apple_objc", *DObj, DObj->getAppleObjCSection(), + DObj->getStringSection(), isLittleEndian()); } DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { @@ -433,7 +437,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() { if (CUIndex) return *CUIndex; - DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0); + DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0); CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO); CUIndex->parse(CUIndexData); @@ -444,7 +448,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() { if (TUIndex) return *TUIndex; - DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0); + DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); TUIndex->parse(TUIndexData); @@ -455,7 +459,7 @@ DWARFGdbIndex &DWARFContext::getGdbIndex() { if (GdbIndex) return *GdbIndex; - DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0); + DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0); GdbIndex = llvm::make_unique<DWARFGdbIndex>(); GdbIndex->parse(GdbIndexData); return *GdbIndex; @@ -465,7 +469,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { if (Abbrev) return Abbrev.get(); - DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); + DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0); Abbrev.reset(new DWARFDebugAbbrev()); Abbrev->extract(abbrData); @@ -476,7 +480,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { if (AbbrevDWO) return AbbrevDWO.get(); - DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0); + DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0); AbbrevDWO.reset(new DWARFDebugAbbrev()); AbbrevDWO->extract(abbrData); return AbbrevDWO.get(); @@ -489,7 +493,7 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() { Loc.reset(new DWARFDebugLoc); // assume all compile units have the same address byte size if (getNumCompileUnits()) { - DWARFDataExtractor LocData(getLocSection(), isLittleEndian(), + DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(), getCompileUnitAtIndex(0)->getAddressByteSize()); Loc->parse(LocData); } @@ -500,7 +504,7 @@ const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() { if (LocDWO) return LocDWO.get(); - DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0); + DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0); LocDWO.reset(new DWARFDebugLocDWO()); LocDWO->parse(LocData); return LocDWO.get(); @@ -528,8 +532,8 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { // provides this information). This problem is fixed in DWARFv4 // See this dwarf-discuss discussion for more details: // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html - DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(), - getAddressSize()); + DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(), + DObj->getAddressSize()); DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */)); DebugFrame->parse(debugFrameData); return DebugFrame.get(); @@ -539,8 +543,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() { if (EHFrame) return EHFrame.get(); - DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(), - getAddressSize()); + DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(), + DObj->getAddressSize()); DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */)); DebugFrame->parse(debugFrameData); return DebugFrame.get(); @@ -550,7 +554,7 @@ const DWARFDebugMacro *DWARFContext::getDebugMacro() { if (Macro) return Macro.get(); - DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0); + DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0); Macro.reset(new DWARFDebugMacro()); Macro->parse(MacinfoData); return Macro.get(); @@ -579,32 +583,32 @@ DWARFContext::getLineTableForUnit(DWARFUnit *U) { return nullptr; // We have to parse it first. - DWARFDataExtractor lineData(U->getLineSection(), isLittleEndian(), + DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(), U->getAddressByteSize()); return Line->getOrParseLineTable(lineData, stmtOffset); } void DWARFContext::parseCompileUnits() { - CUs.parse(*this, getInfoSection()); + CUs.parse(*this, DObj->getInfoSection()); } void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; - forEachTypesSections([&](const DWARFSection &S) { + DObj->forEachTypesSections([&](const DWARFSection &S) { TUs.emplace_back(); TUs.back().parse(*this, S); }); } void DWARFContext::parseDWOCompileUnits() { - DWOCUs.parseDWO(*this, getInfoDWOSection()); + DWOCUs.parseDWO(*this, DObj->getInfoDWOSection()); } void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; - forEachTypesDWOSections([&](const DWARFSection &S) { + DObj->forEachTypesDWOSections([&](const DWARFSection &S) { DWOTUs.emplace_back(); DWOTUs.back().parseDWO(*this, S); }); @@ -779,6 +783,20 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } +/// DWARFContextInMemory is the simplest possible implementation of a +/// DWARFContext. It assumes all content is available in memory and stores +/// pointers to it. +class DWARFContextInMemory : public DWARFContext { +public: + DWARFContextInMemory( + const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, + function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler); + + DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, + uint8_t AddrSize, + bool isLittleEndian = sys::IsLittleEndianHost); +}; + std::shared_ptr<DWARFContext> DWARFContext::getDWOContext(StringRef AbsolutePath) { if (auto S = DWP.lock()) { @@ -796,7 +814,7 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) { SmallString<128> DWPName; Expected<OwningBinary<ObjectFile>> Obj = [&] { if (!CheckedForDWP) { - (getFileName() + ".dwp").toVector(DWPName); + (DObj->getFileName() + ".dwp").toVector(DWPName); auto Obj = object::ObjectFile::createObjectFile(DWPName); if (Obj) { Entry = &DWP; @@ -820,7 +838,7 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) { auto S = std::make_shared<DWOFile>(); S->File = std::move(Obj.get()); - S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary()); + S->Context = DWARFContext::create(*S->File.getBinary()); *Entry = S; auto *Ctxt = S->Context.get(); return std::shared_ptr<DWARFContext>(std::move(S), Ctxt); @@ -906,208 +924,355 @@ static bool isRelocScattered(const object::ObjectFile &Obj, return MachObj->isRelocationScattered(RelocInfo); } -Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec, - StringRef Name, StringRef &Data) { - if (!Decompressor::isCompressed(Sec)) - return Error::success(); +ErrorPolicy DWARFContext::defaultErrorHandler(Error E) { + errs() << "error: " + toString(std::move(E)) << '\n'; + return ErrorPolicy::Continue; +} - Expected<Decompressor> Decompressor = - Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); - if (!Decompressor) - return Decompressor.takeError(); +class DWARFObjInMemory final : public DWARFObject { + bool IsLittleEndian; + uint8_t AddressSize; + StringRef FileName; + + using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap, + std::map<object::SectionRef, unsigned>>; + + TypeSectionMap TypesSections; + TypeSectionMap TypesDWOSections; + + DWARFSectionMap InfoSection; + DWARFSectionMap LocSection; + DWARFSectionMap LineSection; + DWARFSectionMap RangeSection; + DWARFSectionMap StringOffsetSection; + DWARFSectionMap InfoDWOSection; + DWARFSectionMap LineDWOSection; + DWARFSectionMap LocDWOSection; + DWARFSectionMap StringOffsetDWOSection; + DWARFSectionMap RangeDWOSection; + DWARFSectionMap AddrSection; + DWARFSectionMap AppleNamesSection; + DWARFSectionMap AppleTypesSection; + DWARFSectionMap AppleNamespacesSection; + DWARFSectionMap AppleObjCSection; + + DWARFSectionMap *mapNameToDWARFSection(StringRef Name) { + return StringSwitch<DWARFSectionMap *>(Name) + .Case("debug_info", &InfoSection) + .Case("debug_loc", &LocSection) + .Case("debug_line", &LineSection) + .Case("debug_str_offsets", &StringOffsetSection) + .Case("debug_ranges", &RangeSection) + .Case("debug_info.dwo", &InfoDWOSection) + .Case("debug_loc.dwo", &LocDWOSection) + .Case("debug_line.dwo", &LineDWOSection) + .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) + .Case("debug_addr", &AddrSection) + .Case("apple_names", &AppleNamesSection) + .Case("apple_types", &AppleTypesSection) + .Case("apple_namespaces", &AppleNamespacesSection) + .Case("apple_namespac", &AppleNamespacesSection) + .Case("apple_objc", &AppleObjCSection) + .Default(nullptr); + } - SmallString<32> Out; - if (auto Err = Decompressor->resizeAndDecompress(Out)) - return Err; + StringRef AbbrevSection; + StringRef ARangeSection; + StringRef DebugFrameSection; + StringRef EHFrameSection; + StringRef StringSection; + StringRef MacinfoSection; + StringRef PubNamesSection; + StringRef PubTypesSection; + StringRef GnuPubNamesSection; + StringRef AbbrevDWOSection; + StringRef StringDWOSection; + StringRef GnuPubTypesSection; + StringRef CUIndexSection; + StringRef GdbIndexSection; + StringRef TUIndexSection; + + SmallVector<SmallString<32>, 4> UncompressedSections; + + StringRef *mapSectionToMember(StringRef Name) { + if (DWARFSection *Sec = mapNameToDWARFSection(Name)) + return &Sec->Data; + return StringSwitch<StringRef *>(Name) + .Case("debug_abbrev", &AbbrevSection) + .Case("debug_aranges", &ARangeSection) + .Case("debug_frame", &DebugFrameSection) + .Case("eh_frame", &EHFrameSection) + .Case("debug_str", &StringSection) + .Case("debug_macinfo", &MacinfoSection) + .Case("debug_pubnames", &PubNamesSection) + .Case("debug_pubtypes", &PubTypesSection) + .Case("debug_gnu_pubnames", &GnuPubNamesSection) + .Case("debug_gnu_pubtypes", &GnuPubTypesSection) + .Case("debug_abbrev.dwo", &AbbrevDWOSection) + .Case("debug_str.dwo", &StringDWOSection) + .Case("debug_cu_index", &CUIndexSection) + .Case("debug_tu_index", &TUIndexSection) + .Case("gdb_index", &GdbIndexSection) + // Any more debug info sections go here. + .Default(nullptr); + } - UncompressedSections.emplace_back(std::move(Out)); - Data = UncompressedSections.back(); + /// If Sec is compressed section, decompresses and updates its contents + /// provided by Data. Otherwise leaves it unchanged. + Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, + StringRef &Data) { + if (!Decompressor::isCompressed(Sec)) + return Error::success(); - return Error::success(); -} + Expected<Decompressor> Decompressor = + Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8); + if (!Decompressor) + return Decompressor.takeError(); -ErrorPolicy DWARFContextInMemory::defaultErrorHandler(Error E) { - errs() << "error: " + toString(std::move(E)) << '\n'; - return ErrorPolicy::Continue; -} + SmallString<32> Out; + if (auto Err = Decompressor->resizeAndDecompress(Out)) + return Err; -DWARFContextInMemory::DWARFContextInMemory( - const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref<ErrorPolicy(Error)> HandleError) - : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()), - AddressSize(Obj.getBytesInAddress()) { - for (const SectionRef &Section : Obj.sections()) { - StringRef Name; - Section.getName(Name); - // Skip BSS and Virtual sections, they aren't interesting. - if (Section.isBSS() || Section.isVirtual()) - continue; - - StringRef Data; - section_iterator RelocatedSection = Section.getRelocatedSection(); - // Try to obtain an already relocated version of this section. - // Else use the unrelocated section from the object file. We'll have to - // apply relocations ourselves later. - if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) - Section.getContents(Data); - - if (auto Err = maybeDecompress(Section, Name, Data)) { - ErrorPolicy EP = HandleError( - createError("failed to decompress '" + Name + "', ", std::move(Err))); - if (EP == ErrorPolicy::Halt) - return; - continue; - } + UncompressedSections.emplace_back(std::move(Out)); + Data = UncompressedSections.back(); - // Compressed sections names in GNU style starts from ".z", - // at this point section is decompressed and we drop compression prefix. - Name = Name.substr( - Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. + return Error::success(); + } - // Map platform specific debug section names to DWARF standard section - // names. - Name = Obj.mapDebugSectionName(Name); +public: + DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, + uint8_t AddrSize, bool IsLittleEndian) + : IsLittleEndian(IsLittleEndian) { + for (const auto &SecIt : Sections) { + if (StringRef *SectionData = mapSectionToMember(SecIt.first())) + *SectionData = SecIt.second->getBuffer(); + } + } + DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L, + function_ref<ErrorPolicy(Error)> HandleError) + : IsLittleEndian(Obj.isLittleEndian()), + AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()) { + + for (const SectionRef &Section : Obj.sections()) { + StringRef Name; + Section.getName(Name); + // Skip BSS and Virtual sections, they aren't interesting. + if (Section.isBSS() || Section.isVirtual()) + continue; - if (StringRef *SectionData = mapSectionToMember(Name)) { - *SectionData = Data; - if (Name == "debug_ranges") { - // FIXME: Use the other dwo range section when we emit it. - RangeDWOSection.Data = Data; + StringRef Data; + section_iterator RelocatedSection = Section.getRelocatedSection(); + // Try to obtain an already relocated version of this section. + // Else use the unrelocated section from the object file. We'll have to + // apply relocations ourselves later. + if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) + Section.getContents(Data); + + if (auto Err = maybeDecompress(Section, Name, Data)) { + ErrorPolicy EP = HandleError(createError( + "failed to decompress '" + Name + "', ", std::move(Err))); + if (EP == ErrorPolicy::Halt) + return; + continue; + } + + // Compressed sections names in GNU style starts from ".z", + // at this point section is decompressed and we drop compression prefix. + Name = Name.substr( + Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes. + + // Map platform specific debug section names to DWARF standard section + // names. + Name = Obj.mapDebugSectionName(Name); + + if (StringRef *SectionData = mapSectionToMember(Name)) { + *SectionData = Data; + if (Name == "debug_ranges") { + // FIXME: Use the other dwo range section when we emit it. + RangeDWOSection.Data = Data; + } + } else if (Name == "debug_types") { + // Find debug_types data by section rather than name as there are + // multiple, comdat grouped, debug_types sections. + TypesSections[Section].Data = Data; + } else if (Name == "debug_types.dwo") { + TypesDWOSections[Section].Data = Data; } - } else if (Name == "debug_types") { - // Find debug_types data by section rather than name as there are - // multiple, comdat grouped, debug_types sections. - TypesSections[Section].Data = Data; - } else if (Name == "debug_types.dwo") { - TypesDWOSections[Section].Data = Data; - } - if (RelocatedSection == Obj.section_end()) - continue; - - StringRef RelSecName; - StringRef RelSecData; - RelocatedSection->getName(RelSecName); - - // If the section we're relocating was relocated already by the JIT, - // then we used the relocated version above, so we do not need to process - // relocations for it now. - if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) - continue; - - // In Mach-o files, the relocations do not need to be applied if - // there is no load offset to apply. The value read at the - // relocation point already factors in the section address - // (actually applying the relocations will produce wrong results - // as the section address will be added twice). - if (!L && isa<MachOObjectFile>(&Obj)) - continue; - - RelSecName = RelSecName.substr( - RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes. - - // TODO: Add support for relocations in other sections as needed. - // Record relocations for the debug_info and debug_line sections. - DWARFSection *Sec = mapNameToDWARFSection(RelSecName); - RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr; - if (!Map) { - // Find debug_types relocs by section rather than name as there are - // multiple, comdat grouped, debug_types sections. - if (RelSecName == "debug_types") - Map = &TypesSections[*RelocatedSection].Relocs; - else if (RelSecName == "debug_types.dwo") - Map = &TypesDWOSections[*RelocatedSection].Relocs; - else + if (RelocatedSection == Obj.section_end()) continue; - } - if (Section.relocation_begin() == Section.relocation_end()) - continue; + StringRef RelSecName; + StringRef RelSecData; + RelocatedSection->getName(RelSecName); - // Symbol to [address, section index] cache mapping. - std::map<SymbolRef, SymInfo> AddrCache; - for (const RelocationRef &Reloc : Section.relocations()) { - // FIXME: it's not clear how to correctly handle scattered - // relocations. - if (isRelocScattered(Obj, Reloc)) + // If the section we're relocating was relocated already by the JIT, + // then we used the relocated version above, so we do not need to process + // relocations for it now. + if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) continue; - Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache); - if (!SymInfoOrErr) { - if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) - return; + // In Mach-o files, the relocations do not need to be applied if + // there is no load offset to apply. The value read at the + // relocation point already factors in the section address + // (actually applying the relocations will produce wrong results + // as the section address will be added twice). + if (!L && isa<MachOObjectFile>(&Obj)) continue; + + RelSecName = RelSecName.substr( + RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes. + + // TODO: Add support for relocations in other sections as needed. + // Record relocations for the debug_info and debug_line sections. + DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName); + RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr; + if (!Map) { + // Find debug_types relocs by section rather than name as there are + // multiple, comdat grouped, debug_types sections. + if (RelSecName == "debug_types") + Map = + &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection]) + .Relocs; + else if (RelSecName == "debug_types.dwo") + Map = &static_cast<DWARFSectionMap &>( + TypesDWOSections[*RelocatedSection]) + .Relocs; + else + continue; } - object::RelocVisitor V(Obj); - uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address); - if (V.error()) { - SmallString<32> Type; - Reloc.getTypeName(Type); - ErrorPolicy EP = HandleError( - createError("failed to compute relocation: " + Type + ", ", - errorCodeToError(object_error::parse_failed))); - if (EP == ErrorPolicy::Halt) - return; + if (Section.relocation_begin() == Section.relocation_end()) continue; + + // Symbol to [address, section index] cache mapping. + std::map<SymbolRef, SymInfo> AddrCache; + for (const RelocationRef &Reloc : Section.relocations()) { + // FIXME: it's not clear how to correctly handle scattered + // relocations. + if (isRelocScattered(Obj, Reloc)) + continue; + + Expected<SymInfo> SymInfoOrErr = + getSymbolInfo(Obj, Reloc, L, AddrCache); + if (!SymInfoOrErr) { + if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) + return; + continue; + } + + object::RelocVisitor V(Obj); + uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address); + if (V.error()) { + SmallString<32> Type; + Reloc.getTypeName(Type); + ErrorPolicy EP = HandleError( + createError("failed to compute relocation: " + Type + ", ", + errorCodeToError(object_error::parse_failed))); + if (EP == ErrorPolicy::Halt) + return; + continue; + } + RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; + Map->insert({Reloc.getOffset(), Rel}); } - RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; - Map->insert({Reloc.getOffset(), Rel}); } } -} -DWARFContextInMemory::DWARFContextInMemory( - const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize, - bool isLittleEndian) - : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) { - for (const auto &SecIt : Sections) { - if (StringRef *SectionData = mapSectionToMember(SecIt.first())) - *SectionData = SecIt.second->getBuffer(); + Optional<RelocAddrEntry> find(const DWARFSection &S, + uint64_t Pos) const override { + auto &Sec = static_cast<const DWARFSectionMap &>(S); + RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos); + if (AI == Sec.Relocs.end()) + return None; + return AI->second; } -} -DWARFSection *DWARFContextInMemory::mapNameToDWARFSection(StringRef Name) { - return StringSwitch<DWARFSection *>(Name) - .Case("debug_info", &InfoSection) - .Case("debug_loc", &LocSection) - .Case("debug_line", &LineSection) - .Case("debug_str_offsets", &StringOffsetSection) - .Case("debug_ranges", &RangeSection) - .Case("debug_info.dwo", &InfoDWOSection) - .Case("debug_loc.dwo", &LocDWOSection) - .Case("debug_line.dwo", &LineDWOSection) - .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) - .Case("debug_addr", &AddrSection) - .Case("apple_names", &AppleNamesSection) - .Case("apple_types", &AppleTypesSection) - .Case("apple_namespaces", &AppleNamespacesSection) - .Case("apple_namespac", &AppleNamespacesSection) - .Case("apple_objc", &AppleObjCSection) - .Default(nullptr); -} + bool isLittleEndian() const override { return IsLittleEndian; } + StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; } + const DWARFSection &getLineDWOSection() const override { + return LineDWOSection; + } + const DWARFSection &getLocDWOSection() const override { + return LocDWOSection; + } + StringRef getStringDWOSection() const override { return StringDWOSection; } + const DWARFSection &getStringOffsetDWOSection() const override { + return StringOffsetDWOSection; + } + const DWARFSection &getRangeDWOSection() const override { + return RangeDWOSection; + } + const DWARFSection &getAddrSection() const override { return AddrSection; } + StringRef getCUIndexSection() const override { return CUIndexSection; } + StringRef getGdbIndexSection() const override { return GdbIndexSection; } + StringRef getTUIndexSection() const override { return TUIndexSection; } + + // DWARF v5 + const DWARFSection &getStringOffsetSection() const override { + return StringOffsetSection; + } + + // Sections for DWARF5 split dwarf proposal. + const DWARFSection &getInfoDWOSection() const override { + return InfoDWOSection; + } + void forEachTypesDWOSections( + function_ref<void(const DWARFSection &)> F) const override { + for (auto &P : TypesDWOSections) + F(P.second); + } -StringRef *DWARFContextInMemory::mapSectionToMember(StringRef Name) { - if (DWARFSection *Sec = mapNameToDWARFSection(Name)) - return &Sec->Data; - return StringSwitch<StringRef *>(Name) - .Case("debug_abbrev", &AbbrevSection) - .Case("debug_aranges", &ARangeSection) - .Case("debug_frame", &DebugFrameSection) - .Case("eh_frame", &EHFrameSection) - .Case("debug_str", &StringSection) - .Case("debug_macinfo", &MacinfoSection) - .Case("debug_pubnames", &PubNamesSection) - .Case("debug_pubtypes", &PubTypesSection) - .Case("debug_gnu_pubnames", &GnuPubNamesSection) - .Case("debug_gnu_pubtypes", &GnuPubTypesSection) - .Case("debug_abbrev.dwo", &AbbrevDWOSection) - .Case("debug_str.dwo", &StringDWOSection) - .Case("debug_cu_index", &CUIndexSection) - .Case("debug_tu_index", &TUIndexSection) - .Case("gdb_index", &GdbIndexSection) - // Any more debug info sections go here. - .Default(nullptr); + StringRef getAbbrevSection() const override { return AbbrevSection; } + const DWARFSection &getLocSection() const override { return LocSection; } + StringRef getARangeSection() const override { return ARangeSection; } + StringRef getDebugFrameSection() const override { return DebugFrameSection; } + StringRef getEHFrameSection() const override { return EHFrameSection; } + const DWARFSection &getLineSection() const override { return LineSection; } + StringRef getStringSection() const override { return StringSection; } + const DWARFSection &getRangeSection() const override { return RangeSection; } + StringRef getMacinfoSection() const override { return MacinfoSection; } + StringRef getPubNamesSection() const override { return PubNamesSection; } + StringRef getPubTypesSection() const override { return PubTypesSection; } + StringRef getGnuPubNamesSection() const override { + return GnuPubNamesSection; + } + StringRef getGnuPubTypesSection() const override { + return GnuPubTypesSection; + } + const DWARFSection &getAppleNamesSection() const override { + return AppleNamesSection; + } + const DWARFSection &getAppleTypesSection() const override { + return AppleTypesSection; + } + const DWARFSection &getAppleNamespacesSection() const override { + return AppleNamespacesSection; + } + const DWARFSection &getAppleObjCSection() const override { + return AppleObjCSection; + } + + StringRef getFileName() const override { return FileName; } + uint8_t getAddressSize() const override { return AddressSize; } + const DWARFSection &getInfoSection() const override { return InfoSection; } + void forEachTypesSections( + function_ref<void(const DWARFSection &)> F) const override { + for (auto &P : TypesSections) + F(P.second); + } +}; + +std::unique_ptr<DWARFContext> +DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, + function_ref<ErrorPolicy(Error)> HandleError) { + auto DObj = make_unique<DWARFObjInMemory>(Obj, L, HandleError); + return make_unique<DWARFContext>(std::move(DObj)); } -void DWARFContextInMemory::anchor() {} +std::unique_ptr<DWARFContext> +DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, + uint8_t AddrSize, bool isLittleEndian) { + auto DObj = make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); + return make_unique<DWARFContext>(std::move(DObj)); +} diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index 001097e56c7..a40635568cd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -8,17 +8,18 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" using namespace llvm; uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, uint64_t *SecNdx) const { - if (!RelocMap) + if (!Section) return getUnsigned(Off, Size); - RelocAddrMap::const_iterator AI = RelocMap->find(*Off); - if (AI == RelocMap->end()) + Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off); + if (!Rel) return getUnsigned(Off, Size); if (SecNdx) - *SecNdx = AI->second.SectionIndex; - return getUnsigned(Off, Size) + AI->second.Value; + *SecNdx = Rel->SectionIndex; + return getUnsigned(Off, Size) + Rel->Value; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp index 6601393d745..65c486a6cf3 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -43,7 +43,8 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) { return; // Extract aranges from .debug_aranges section. - DataExtractor ArangesData(CTX->getARangeSection(), CTX->isLittleEndian(), 0); + DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(), + CTX->isLittleEndian(), 0); extract(ArangesData); // Generate aranges from DIEs: even if .debug_aranges section is present, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 043bdb874f4..2bcda237a4c 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -30,17 +30,19 @@ using namespace llvm; using namespace dwarf; void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) { - parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(), - C.getStringSection(), C.getStringOffsetSection(), - &C.getAddrSection(), C.getLineSection(), C.isLittleEndian(), false); + const DWARFObject &D = C.getDWARFObj(); + parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(), + D.getStringSection(), D.getStringOffsetSection(), + &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false); } void DWARFUnitSectionBase::parseDWO(DWARFContext &C, const DWARFSection &DWOSection, DWARFUnitIndex *Index) { - parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(), - C.getStringDWOSection(), C.getStringOffsetDWOSection(), - &C.getAddrSection(), C.getLineDWOSection(), C.isLittleEndian(), + const DWARFObject &D = C.getDWARFObj(); + parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), + D.getStringDWOSection(), D.getStringOffsetDWOSection(), + &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), true); } @@ -59,13 +61,18 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, DWARFUnit::~DWARFUnit() = default; +DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const { + return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian, + getAddressByteSize()); +} + bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const { uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) return false; - DWARFDataExtractor DA(*AddrOffsetSection, isLittleEndian, - getAddressByteSize()); + DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection, + isLittleEndian, getAddressByteSize()); Result = DA.getRelocatedAddress(&Offset); return true; } @@ -76,7 +83,8 @@ bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index, uint32_t Offset = StringOffsetSectionBase + Index * ItemSize; if (StringOffsetSection.Data.size() < Offset + ItemSize) return false; - DWARFDataExtractor DA(StringOffsetSection, isLittleEndian, 0); + DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, + isLittleEndian, 0); Result = DA.getRelocatedValue(ItemSize, &Offset); return true; } @@ -141,8 +149,8 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset, DWARFDebugRangeList &RangeList) const { // Require that compile unit is extracted. assert(!DieArray.empty()); - DWARFDataExtractor RangesData(*RangeSection, isLittleEndian, - getAddressByteSize()); + DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, + isLittleEndian, getAddressByteSize()); uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; return RangeList.extract(RangesData, &ActualRangeListOffset); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 6cf44ffa379..50fc45a9e37 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -105,8 +105,9 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit) { bool DWARFVerifier::handleDebugInfo() { OS << "Verifying .debug_info Unit Header Chain...\n"; - DWARFDataExtractor DebugInfoData(DCtx.getInfoSection(), DCtx.isLittleEndian(), - 0); + const DWARFObject &DObj = DCtx.getDWARFObj(); + DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(), + DCtx.isLittleEndian(), 0); uint32_t NumDebugInfoErrors = 0; uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0; uint8_t UnitType = 0; @@ -127,10 +128,10 @@ bool DWARFVerifier::handleDebugInfo() { case dwarf::DW_UT_split_type: { DWARFUnitSection<DWARFTypeUnit> TUSection{}; Unit.reset(new DWARFTypeUnit( - DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(), - &DCtx.getRangeSection(), DCtx.getStringSection(), - DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(), - DCtx.getLineSection(), DCtx.isLittleEndian(), false, TUSection, + DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(), + &DObj.getRangeSection(), DObj.getStringSection(), + DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), + DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection, nullptr)); break; } @@ -143,10 +144,10 @@ bool DWARFVerifier::handleDebugInfo() { case 0: { DWARFUnitSection<DWARFCompileUnit> CUSection{}; Unit.reset(new DWARFCompileUnit( - DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(), - &DCtx.getRangeSection(), DCtx.getStringSection(), - DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(), - DCtx.getLineSection(), DCtx.isLittleEndian(), false, CUSection, + DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(), + &DObj.getRangeSection(), DObj.getStringSection(), + DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), + DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection, nullptr)); break; } @@ -169,13 +170,14 @@ bool DWARFVerifier::handleDebugInfo() { unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue) { + const DWARFObject &DObj = DCtx.getDWARFObj(); unsigned NumErrors = 0; const auto Attr = AttrValue.Attr; switch (Attr) { case DW_AT_ranges: // Make sure the offset in the DW_AT_ranges attribute is valid. if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) { - if (*SectionOffset >= DCtx.getRangeSection().Data.size()) { + if (*SectionOffset >= DObj.getRangeSection().Data.size()) { ++NumErrors; OS << "error: DW_AT_ranges offset is beyond .debug_ranges " "bounds:\n"; @@ -192,7 +194,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, case DW_AT_stmt_list: // Make sure the offset in the DW_AT_stmt_list attribute is valid. if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) { - if (*SectionOffset >= DCtx.getLineSection().Data.size()) { + if (*SectionOffset >= DObj.getLineSection().Data.size()) { ++NumErrors; OS << "error: DW_AT_stmt_list offset is beyond .debug_line " "bounds: " @@ -216,6 +218,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue) { + const DWARFObject &DObj = DCtx.getDWARFObj(); unsigned NumErrors = 0; const auto Form = AttrValue.Value.getForm(); switch (Form) { @@ -253,7 +256,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, Optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); assert(RefVal); if (RefVal) { - if (*RefVal >= DCtx.getInfoSection().Data.size()) { + if (*RefVal >= DObj.getInfoSection().Data.size()) { ++NumErrors; OS << "error: DW_FORM_ref_addr offset beyond .debug_info " "bounds:\n"; @@ -270,7 +273,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, case DW_FORM_strp: { auto SecOffset = AttrValue.Value.getAsSectionOffset(); assert(SecOffset); // DW_FORM_strp is a section offset. - if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) { + if (SecOffset && *SecOffset >= DObj.getStringSection().size()) { ++NumErrors; OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n"; Die.dump(OS, 0); @@ -318,7 +321,7 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() { continue; const uint32_t LineTableOffset = *StmtSectionOffset; auto LineTable = DCtx.getLineTableForUnit(CU.get()); - if (LineTableOffset < DCtx.getLineSection().Data.size()) { + if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) { if (!LineTable) { ++NumDebugLineErrors; OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset) @@ -408,10 +411,10 @@ bool DWARFVerifier::handleDebugLine() { bool DWARFVerifier::handleAppleNames() { NumAppleNamesErrors = 0; - - DWARFDataExtractor AppleNamesSection(DCtx.getAppleNamesSection(), + const DWARFObject &D = DCtx.getDWARFObj(); + DWARFDataExtractor AppleNamesSection(D, D.getAppleNamesSection(), DCtx.isLittleEndian(), 0); - DataExtractor StrData(DCtx.getStringSection(), DCtx.isLittleEndian(), 0); + DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0); DWARFAcceleratorTable AppleNames(AppleNamesSection, StrData); if (!AppleNames.extract()) { diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 19711ca58c6..1d8b4321647 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -409,7 +409,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { } } if (!Context) - Context.reset(new DWARFContextInMemory(*Objects.second)); + Context = DWARFContext::create(*Objects.second); assert(Context); auto InfoOrErr = SymbolizableObjectFile::create(Objects.first, std::move(Context)); |