aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFContext.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp406
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();
}