diff options
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFContext.cpp')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 406 |
1 files changed, 229 insertions, 177 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index aaa6d5250f23..bf6219497770 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -45,7 +45,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstdint> @@ -66,8 +65,12 @@ using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj, - std::string DWPName) - : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {} + std::string DWPName, + std::function<void(Error)> RecoverableErrorHandler, + std::function<void(Error)> WarningHandler) + : DIContext(CK_DWARF), DWPName(std::move(DWPName)), + RecoverableErrorHandler(RecoverableErrorHandler), + WarningHandler(WarningHandler), DObj(std::move(DObj)) {} DWARFContext::~DWARFContext() = default; @@ -130,10 +133,21 @@ collectContributionData(DWARFContext::unit_iterator_range Units) { return Contributions; } -static void dumpDWARFv5StringOffsetsSection( - raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, - const DWARFSection &StringOffsetsSection, StringRef StringSection, - DWARFContext::unit_iterator_range Units, bool LittleEndian) { +// Dump a DWARF string offsets section. This may be a DWARF v5 formatted +// string offsets section, where each compile or type unit contributes a +// number of entries (string offsets), with each contribution preceded by +// a header containing size and version number. Alternatively, it may be a +// monolithic series of string offsets, as generated by the pre-DWARF v5 +// implementation of split DWARF; however, in that case we still need to +// collect contributions of units because the size of the offsets (4 or 8 +// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64). +static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts, + StringRef SectionName, + const DWARFObject &Obj, + const DWARFSection &StringOffsetsSection, + StringRef StringSection, + DWARFContext::unit_iterator_range Units, + bool LittleEndian) { auto Contributions = collectContributionData(Units); DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); DataExtractor StrData(StringSection, LittleEndian, 0); @@ -148,6 +162,7 @@ static void dumpDWARFv5StringOffsetsSection( } dwarf::DwarfFormat Format = Contribution->getFormat(); + int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format); uint16_t Version = Contribution->getVersion(); uint64_t ContributionHeader = Contribution->Base; // In DWARF v5 there is a contribution header that immediately precedes @@ -159,10 +174,10 @@ static void dumpDWARFv5StringOffsetsSection( // Detect overlapping contributions. if (Offset > ContributionHeader) { - WithColor::error() - << "overlapping contributions to string offsets table in section ." - << SectionName << ".\n"; - return; + DumpOpts.RecoverableErrorHandler(createStringError( + errc::invalid_argument, + "overlapping contributions to string offsets table in section .%s.", + SectionName.data())); } // Report a gap in the table. if (Offset < ContributionHeader) { @@ -175,7 +190,7 @@ static void dumpDWARFv5StringOffsetsSection( // version field and the padding, a total of 4 bytes). Add them back in // for reporting. OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4)) - << ", Format = " << (Format == DWARF32 ? "DWARF32" : "DWARF64") + << ", Format = " << dwarf::FormatString(Format) << ", Version = " << Version << "\n"; Offset = Contribution->Base; @@ -184,7 +199,7 @@ static void dumpDWARFv5StringOffsetsSection( OS << format("0x%8.8" PRIx64 ": ", Offset); uint64_t StringOffset = StrOffsetExt.getRelocatedValue(EntrySize, &Offset); - OS << format("%8.8" PRIx64 " ", StringOffset); + OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset); const char *S = StrData.getCStr(&StringOffset); if (S) OS << format("\"%s\"", S); @@ -198,47 +213,6 @@ static void dumpDWARFv5StringOffsetsSection( } } -// Dump a DWARF string offsets section. This may be a DWARF v5 formatted -// string offsets section, where each compile or type unit contributes a -// number of entries (string offsets), with each contribution preceded by -// a header containing size and version number. Alternatively, it may be a -// 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, - DWARFContext::unit_iterator_range Units, - bool LittleEndian, unsigned MaxVersion) { - // If we have at least one (compile or type) unit with DWARF v5 or greater, - // we assume that the section is formatted like a DWARF v5 string offsets - // section. - if (MaxVersion >= 5) - dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection, - StringSection, Units, LittleEndian); - else { - DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0); - uint64_t offset = 0; - uint64_t size = StringOffsetsSection.Data.size(); - // Ensure that size is a multiple of the size of an entry. - if (size & ((uint64_t)(sizeof(uint32_t) - 1))) { - OS << "error: size of ." << SectionName << " is not a multiple of " - << sizeof(uint32_t) << ".\n"; - size &= -(uint64_t)sizeof(uint32_t); - } - DataExtractor StrData(StringSection, LittleEndian, 0); - while (offset < size) { - OS << format("0x%8.8" PRIx64 ": ", offset); - uint64_t StringOffset = strOffsetExt.getU32(&offset); - OS << format("%8.8" PRIx64 " ", StringOffset); - const char *S = StrData.getCStr(&StringOffset); - if (S) - OS << format("\"%s\"", S); - OS << "\n"; - } - } -} - // Dump the .debug_addr section. static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, @@ -248,16 +222,17 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DWARFDebugAddrTable AddrTable; uint64_t TableOffset = Offset; if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize, - DWARFContext::dumpWarning)) { - WithColor::error() << toString(std::move(Err)) << '\n'; + DumpOpts.WarningHandler)) { + DumpOpts.RecoverableErrorHandler(std::move(Err)); // Keep going after an error, if we can, assuming that the length field // could be read. If it couldn't, stop reading the section. - if (!AddrTable.hasValidLength()) - break; - Offset = TableOffset + AddrTable.getLength(); - } else { - AddrTable.dump(OS, DumpOpts); + if (auto TableLength = AddrTable.getFullLength()) { + Offset = TableOffset + *TableLength; + continue; + } + break; } + AddrTable.dump(OS, DumpOpts); } } @@ -272,7 +247,7 @@ static void dumpRnglistsSection( llvm::DWARFDebugRnglistTable Rnglists; uint64_t TableOffset = Offset; if (Error Err = Rnglists.extract(rnglistData, &Offset)) { - WithColor::error() << toString(std::move(Err)) << '\n'; + DumpOpts.RecoverableErrorHandler(std::move(Err)); uint64_t Length = Rnglists.length(); // Keep going after an error, if we can, assuming that the length field // could be read. If it couldn't, stop reading the section. @@ -285,6 +260,48 @@ static void dumpRnglistsSection( } } +std::unique_ptr<DWARFDebugMacro> +DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) { + auto Macro = std::make_unique<DWARFDebugMacro>(); + auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) { + if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection + ? compile_units() + : dwo_compile_units(), + SectionType == MacroSection + ? getStringExtractor() + : getStringDWOExtractor(), + Data) + : Macro->parseMacinfo(Data)) { + RecoverableErrorHandler(std::move(Err)); + Macro = nullptr; + } + }; + switch (SectionType) { + case MacinfoSection: { + DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0); + ParseAndDump(Data, /*IsMacro=*/false); + break; + } + case MacinfoDwoSection: { + DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0); + ParseAndDump(Data, /*IsMacro=*/false); + break; + } + case MacroSection: { + DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(), + 0); + ParseAndDump(Data, /*IsMacro=*/true); + break; + } + case MacroDwoSection: { + DWARFDataExtractor Data(DObj->getMacroDWOSection(), isLittleEndian(), 0); + ParseAndDump(Data, /*IsMacro=*/true); + break; + } + } + return Macro; +} + static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const MCRegisterInfo *MRI, @@ -295,7 +312,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, while (Data.isValidOffset(Offset)) { DWARFListTableHeader Header(".debug_loclists", "locations"); if (Error E = Header.extract(Data, &Offset)) { - WithColor::error() << toString(std::move(E)) << '\n'; + DumpOpts.RecoverableErrorHandler(std::move(E)); return; } @@ -319,10 +336,16 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, } } +static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, + DWARFDataExtractor Data, bool GnuStyle) { + DWARFDebugPubTable Table; + Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler); + Table.dump(OS); +} + void DWARFContext::dump( raw_ostream &OS, DIDumpOptions DumpOpts, std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { - uint64_t DumpType = DumpOpts.DumpType; StringRef Extension = sys::path::extension(DObj->getFileName()); @@ -430,31 +453,61 @@ void DWARFContext::dump( } } - if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, - DObj->getFrameSection().Data)) - getDebugFrame()->dump(OS, getRegisterInfo(), *Off); + if (const Optional<uint64_t> *Off = + shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, + DObj->getFrameSection().Data)) { + if (Expected<const DWARFDebugFrame *> DF = getDebugFrame()) + (*DF)->dump(OS, getRegisterInfo(), *Off); + else + RecoverableErrorHandler(DF.takeError()); + } - if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, - DObj->getEHFrameSection().Data)) - getEHFrame()->dump(OS, getRegisterInfo(), *Off); + if (const Optional<uint64_t> *Off = + shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, + DObj->getEHFrameSection().Data)) { + if (Expected<const DWARFDebugFrame *> DF = getEHFrame()) + (*DF)->dump(OS, getRegisterInfo(), *Off); + else + RecoverableErrorHandler(DF.takeError()); + } - if (DumpType & DIDT_DebugMacro) { - if (Explicit || !getDebugMacro()->empty()) { - OS << "\n.debug_macinfo contents:\n"; - getDebugMacro()->dump(OS); - } else if (ExplicitDWO || !getDebugMacroDWO()->empty()) { - OS << "\n.debug_macinfo.dwo contents:\n"; - getDebugMacroDWO()->dump(OS); - } + if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro, + DObj->getMacroSection().Data)) { + if (auto Macro = getDebugMacro()) + Macro->dump(OS); + } + + if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro, + DObj->getMacroDWOSection())) { + if (auto MacroDWO = getDebugMacroDWO()) + MacroDWO->dump(OS); + } + + if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro, + DObj->getMacinfoSection())) { + if (auto Macinfo = getDebugMacinfo()) + Macinfo->dump(OS); + } + + if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro, + DObj->getMacinfoDWOSection())) { + if (auto MacinfoDWO = getDebugMacinfoDWO()) + MacinfoDWO->dump(OS); } if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges, DObj->getArangesSection())) { uint64_t offset = 0; - DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0); + DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), + 0); DWARFDebugArangeSet set; - while (set.extract(arangesData, &offset)) + while (arangesData.isValidOffset(offset)) { + if (Error E = set.extract(arangesData, &offset)) { + RecoverableErrorHandler(std::move(E)); + break; + } set.dump(OS); + } } auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser, @@ -462,18 +515,13 @@ void DWARFContext::dump( Optional<uint64_t> DumpOffset) { while (!Parser.done()) { if (DumpOffset && Parser.getOffset() != *DumpOffset) { - Parser.skip(dumpWarning); + Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler); continue; } OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset()) << "]\n"; - if (DumpOpts.Verbose) { - Parser.parseNext(dumpWarning, dumpWarning, &OS); - } else { - DWARFDebugLine::LineTable LineTable = - Parser.parseNext(dumpWarning, dumpWarning); - LineTable.dump(OS, DumpOpts); - } + Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS, + DumpOpts.Verbose); } }; @@ -555,7 +603,7 @@ void DWARFContext::dump( DWARFDebugRangeList rangeList; while (rangesData.isValidOffset(offset)) { if (Error E = rangeList.extract(rangesData, &offset)) { - WithColor::error() << toString(std::move(E)) << '\n'; + DumpOpts.RecoverableErrorHandler(std::move(E)); break; } rangeList.dump(OS); @@ -585,39 +633,44 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames, - DObj->getPubnamesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getPubnamesSection(), isLittleEndian(), false) - .dump(OS); + DObj->getPubnamesSection().Data)) { + DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(), + isLittleEndian(), 0); + dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false); + } if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes, - DObj->getPubtypesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getPubtypesSection(), isLittleEndian(), false) - .dump(OS); + DObj->getPubtypesSection().Data)) { + DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(), + isLittleEndian(), 0); + dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false); + } if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames, - DObj->getGnuPubnamesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getGnuPubnamesSection(), isLittleEndian(), - true /* GnuStyle */) - .dump(OS); + DObj->getGnuPubnamesSection().Data)) { + DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(), + isLittleEndian(), 0); + dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true); + } if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes, - DObj->getGnuPubtypesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getGnuPubtypesSection(), isLittleEndian(), - true /* GnuStyle */) - .dump(OS); + DObj->getGnuPubtypesSection().Data)) { + DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(), + isLittleEndian(), 0); + dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true); + } if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets, DObj->getStrOffsetsSection().Data)) - dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj, - DObj->getStrOffsetsSection(), - DObj->getStrSection(), normal_units(), - isLittleEndian(), getMaxVersion()); + dumpStringOffsetsSection( + OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(), + DObj->getStrSection(), normal_units(), isLittleEndian()); if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets, DObj->getStrOffsetsDWOSection().Data)) - dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj, + dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj, DObj->getStrOffsetsDWOSection(), DObj->getStrDWOSection(), dwo_units(), - isLittleEndian(), getMaxDWOVersion()); + isLittleEndian()); if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex, DObj->getGdbIndexSection())) { @@ -711,7 +764,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() { DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); - TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); + TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES); TUIndex->parse(TUIndexData); return *TUIndex; } @@ -770,7 +823,7 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() { return Aranges.get(); } -const DWARFDebugFrame *DWARFContext::getDebugFrame() { +Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() { if (DebugFrame) return DebugFrame.get(); @@ -785,41 +838,50 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(), isLittleEndian(), DObj->getAddressSize()); - DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */)); - DebugFrame->parse(debugFrameData); + auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false); + if (Error E = DF->parse(debugFrameData)) + return std::move(E); + + DebugFrame.swap(DF); return DebugFrame.get(); } -const DWARFDebugFrame *DWARFContext::getEHFrame() { +Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() { if (EHFrame) return EHFrame.get(); DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(), isLittleEndian(), DObj->getAddressSize()); - DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */)); - DebugFrame->parse(debugFrameData); + + auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true); + if (Error E = DF->parse(debugFrameData)) + return std::move(E); + DebugFrame.swap(DF); return DebugFrame.get(); } -const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() { - if (MacroDWO) - return MacroDWO.get(); +const DWARFDebugMacro *DWARFContext::getDebugMacro() { + if (!Macro) + Macro = parseMacroOrMacinfo(MacroSection); + return Macro.get(); +} - DataExtractor MacinfoDWOData(DObj->getMacinfoDWOSection(), isLittleEndian(), - 0); - MacroDWO.reset(new DWARFDebugMacro()); - MacroDWO->parse(MacinfoDWOData); +const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() { + if (!MacroDWO) + MacroDWO = parseMacroOrMacinfo(MacroDwoSection); return MacroDWO.get(); } -const DWARFDebugMacro *DWARFContext::getDebugMacro() { - if (Macro) - return Macro.get(); +const DWARFDebugMacro *DWARFContext::getDebugMacinfo() { + if (!Macinfo) + Macinfo = parseMacroOrMacinfo(MacinfoSection); + return Macinfo.get(); +} - DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0); - Macro.reset(new DWARFDebugMacro()); - Macro->parse(MacinfoData); - return Macro.get(); +const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() { + if (!MacinfoDWO) + MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection); + return MacinfoDWO.get(); } template <typename T> @@ -865,16 +927,16 @@ const AppleAcceleratorTable &DWARFContext::getAppleObjC() { const DWARFDebugLine::LineTable * DWARFContext::getLineTableForUnit(DWARFUnit *U) { Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable = - getLineTableForUnit(U, dumpWarning); + getLineTableForUnit(U, WarningHandler); if (!ExpectedLineTable) { - dumpWarning(ExpectedLineTable.takeError()); + WarningHandler(ExpectedLineTable.takeError()); return nullptr; } return *ExpectedLineTable; } Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit( - DWARFUnit *U, function_ref<void(Error)> RecoverableErrorCallback) { + DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) { if (!Line) Line.reset(new DWARFDebugLine); @@ -899,7 +961,7 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit( DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(), U->getAddressByteSize()); return Line->getOrParseLineTable(lineData, stmtOffset, *this, U, - RecoverableErrorCallback); + RecoverableErrorHandler); } void DWARFContext::parseNormalUnits() { @@ -910,7 +972,7 @@ void DWARFContext::parseNormalUnits() { }); NormalUnits.finishedInfoUnits(); DObj->forEachTypesSections([&](const DWARFSection &S) { - NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES); + NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES); }); } @@ -922,7 +984,7 @@ void DWARFContext::parseDWOUnits(bool Lazy) { }); DWOUnits.finishedInfoUnits(); DObj->forEachTypesDWOSections([&](const DWARFSection &S) { - DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy); + DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy); }); } @@ -1418,11 +1480,6 @@ static bool isRelocScattered(const object::ObjectFile &Obj, return MachObj->isRelocationScattered(RelocInfo); } -ErrorPolicy DWARFContext::defaultErrorHandler(Error E) { - WithColor::error() << toString(std::move(E)) << '\n'; - return ErrorPolicy::Continue; -} - namespace { struct DWARFSectionMap final : public DWARFSection { RelocAddrMap Relocs; @@ -1467,6 +1524,7 @@ class DWARFObjInMemory final : public DWARFObject { DWARFSectionMap PubtypesSection; DWARFSectionMap GnuPubnamesSection; DWARFSectionMap GnuPubtypesSection; + DWARFSectionMap MacroSection; DWARFSectionMap *mapNameToDWARFSection(StringRef Name) { return StringSwitch<DWARFSectionMap *>(Name) @@ -1494,6 +1552,7 @@ class DWARFObjInMemory final : public DWARFObject { .Case("apple_namespaces", &AppleNamespacesSection) .Case("apple_namespac", &AppleNamespacesSection) .Case("apple_objc", &AppleObjCSection) + .Case("debug_macro", &MacroSection) .Default(nullptr); } @@ -1502,6 +1561,7 @@ class DWARFObjInMemory final : public DWARFObject { StringRef StrSection; StringRef MacinfoSection; StringRef MacinfoDWOSection; + StringRef MacroDWOSection; StringRef AbbrevDWOSection; StringRef StrDWOSection; StringRef CUIndexSection; @@ -1522,6 +1582,7 @@ class DWARFObjInMemory final : public DWARFObject { .Case("debug_str", &StrSection) .Case("debug_macinfo", &MacinfoSection) .Case("debug_macinfo.dwo", &MacinfoDWOSection) + .Case("debug_macro.dwo", &MacroDWOSection) .Case("debug_abbrev.dwo", &AbbrevDWOSection) .Case("debug_str.dwo", &StrDWOSection) .Case("debug_cu_index", &CUIndexSection) @@ -1574,7 +1635,7 @@ public: } } DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref<ErrorPolicy(Error)> HandleError) + function_ref<void(Error)> HandleError, function_ref<void(Error)> HandleWarning ) : IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()), Obj(&Obj) { @@ -1601,10 +1662,8 @@ public: StringRef Data; Expected<section_iterator> SecOrErr = Section.getRelocatedSection(); if (!SecOrErr) { - ErrorPolicy EP = HandleError(createError( - "failed to get relocated section: ", SecOrErr.takeError())); - if (EP == ErrorPolicy::Halt) - return; + HandleError(createError("failed to get relocated section: ", + SecOrErr.takeError())); continue; } @@ -1622,10 +1681,8 @@ public: } if (auto Err = maybeDecompress(Section, Name, Data)) { - ErrorPolicy EP = HandleError(createError( - "failed to decompress '" + Name + "', ", std::move(Err))); - if (EP == ErrorPolicy::Halt) - return; + HandleError(createError("failed to decompress '" + Name + "', ", + std::move(Err))); continue; } @@ -1726,8 +1783,7 @@ public: Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache); if (!SymInfoOrErr) { - if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) - return; + HandleError(SymInfoOrErr.takeError()); continue; } @@ -1747,10 +1803,8 @@ public: if (!I.second) { RelocAddrEntry &entry = I.first->getSecond(); if (entry.Reloc2) { - ErrorPolicy EP = HandleError(createError( + HandleError(createError( "At most two relocations per offset are supported")); - if (EP == ErrorPolicy::Halt) - return; } entry.Reloc2 = Reloc; entry.SymbolValue2 = SymInfoOrErr->Address; @@ -1758,11 +1812,10 @@ public: } else { SmallString<32> Type; Reloc.getTypeName(Type); - ErrorPolicy EP = HandleError( + // FIXME: Support more relocations & change this to an error + HandleWarning( createError("failed to compute relocation: " + Type + ", ", errorCodeToError(object_error::parse_failed))); - if (EP == ErrorPolicy::Halt) - return; } } } @@ -1847,6 +1900,8 @@ public: const DWARFSection &getRnglistsSection() const override { return RnglistsSection; } + const DWARFSection &getMacroSection() const override { return MacroSection; } + StringRef getMacroDWOSection() const override { return MacroDWOSection; } StringRef getMacinfoSection() const override { return MacinfoSection; } StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; } const DWARFSection &getPubnamesSection() const override { return PubnamesSection; } @@ -1890,18 +1945,25 @@ public: std::unique_ptr<DWARFContext> DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref<ErrorPolicy(Error)> HandleError, - std::string DWPName) { - auto DObj = std::make_unique<DWARFObjInMemory>(Obj, L, HandleError); - return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName)); + std::string DWPName, + std::function<void(Error)> RecoverableErrorHandler, + std::function<void(Error)> WarningHandler) { + auto DObj = + std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler, WarningHandler); + return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName), + RecoverableErrorHandler, + WarningHandler); } std::unique_ptr<DWARFContext> DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, - uint8_t AddrSize, bool isLittleEndian) { + uint8_t AddrSize, bool isLittleEndian, + std::function<void(Error)> RecoverableErrorHandler, + std::function<void(Error)> WarningHandler) { auto DObj = std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); - return std::make_unique<DWARFContext>(std::move(DObj), ""); + return std::make_unique<DWARFContext>( + std::move(DObj), "", RecoverableErrorHandler, WarningHandler); } Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { @@ -1924,19 +1986,9 @@ Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { uint8_t DWARFContext::getCUAddrSize() { // In theory, different compile units may have different address byte // sizes, but for simplicity we just use the address byte size of the - // last compile unit. In practice the address size field is repeated across + // first compile unit. In practice the address size field is repeated across // various DWARF headers (at least in version 5) to make it easier to dump // them independently, not to enable varying the address size. - uint8_t Addr = 0; - for (const auto &CU : compile_units()) { - Addr = CU->getAddressByteSize(); - break; - } - return Addr; -} - -void DWARFContext::dumpWarning(Error Warning) { - handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) { - WithColor::warning() << Info.message() << '\n'; - }); + unit_iterator_range CUs = compile_units(); + return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize(); } |