aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo/DWARF/DWARFContext.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/DebugInfo/DWARF/DWARFContext.cpp
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
downloadsrc-d8e91e46262bc44006913e6796843909f1ac7bcd.tar.gz
src-d8e91e46262bc44006913e6796843909f1ac7bcd.zip
Vendor import of llvm trunk r351319 (just before the release_80 branchvendor/llvm/llvm-trunk-r351319
Notes
Notes: svn path=/vendor/llvm/dist/; revision=343171 svn path=/vendor/llvm/llvm-trunk-r351319/; revision=343172; tag=vendor/llvm/llvm-trunk-r351319
Diffstat (limited to 'lib/DebugInfo/DWARF/DWARFContext.cpp')
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp406
1 files changed, 235 insertions, 171 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index 9d2554ff9e2e..e6620ee3dd1d 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -99,22 +99,18 @@ using ContributionCollection =
// Collect all the contributions to the string offsets table from all units,
// sort them by their starting offsets and remove duplicates.
static ContributionCollection
-collectContributionData(DWARFContext::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs) {
+collectContributionData(DWARFContext::unit_iterator_range Units) {
ContributionCollection Contributions;
- for (const auto &CU : CUs)
- Contributions.push_back(CU->getStringOffsetsTableContribution());
- for (const auto &TUS : TUSs)
- for (const auto &TU : TUS)
- Contributions.push_back(TU->getStringOffsetsTableContribution());
-
+ for (const auto &U : Units)
+ Contributions.push_back(U->getStringOffsetsTableContribution());
// Sort the contributions so that any invalid ones are placed at
// the start of the contributions vector. This way they are reported
// first.
- llvm::sort(Contributions.begin(), Contributions.end(),
+ llvm::sort(Contributions,
[](const Optional<StrOffsetsContributionDescriptor> &L,
const Optional<StrOffsetsContributionDescriptor> &R) {
- if (L && R) return L->Base < R->Base;
+ if (L && R)
+ return L->Base < R->Base;
return R.hasValue();
});
@@ -136,9 +132,8 @@ collectContributionData(DWARFContext::cu_iterator_range CUs,
static void dumpDWARFv5StringOffsetsSection(
raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
const DWARFSection &StringOffsetsSection, StringRef StringSection,
- DWARFContext::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian) {
- auto Contributions = collectContributionData(CUs, TUSs);
+ DWARFContext::unit_iterator_range Units, bool LittleEndian) {
+ auto Contributions = collectContributionData(Units);
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
DataExtractor StrData(StringSection, LittleEndian, 0);
uint64_t SectionSize = StringOffsetsSection.Data.size();
@@ -215,18 +210,18 @@ static void dumpDWARFv5StringOffsetsSection(
// 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::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian,
- unsigned MaxVersion) {
+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, CUs, TUSs, LittleEndian);
+ StringSection, Units, LittleEndian);
else {
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
uint32_t offset = 0;
@@ -254,19 +249,12 @@ static void dumpStringOffsetsSection(
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
DIDumpOptions DumpOpts, uint16_t Version,
uint8_t AddrSize) {
- // TODO: Make this more general: add callback types to Error.h, create
- // implementation and make all DWARF classes use them.
- static auto WarnCallback = [](Error Warn) {
- handleAllErrors(std::move(Warn), [](ErrorInfoBase &Info) {
- WithColor::warning() << Info.message() << '\n';
- });
- };
uint32_t Offset = 0;
while (AddrData.isValidOffset(Offset)) {
DWARFDebugAddrTable AddrTable;
uint32_t TableOffset = Offset;
- if (Error Err = AddrTable.extract(AddrData, &Offset, Version,
- AddrSize, WarnCallback)) {
+ if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
+ DWARFContext::dumpWarning)) {
WithColor::error() << toString(std::move(Err)) << '\n';
// Keep going after an error, if we can, assuming that the length field
// could be read. If it couldn't, stop reading the section.
@@ -281,9 +269,11 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
}
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
-static void dumpRnglistsSection(raw_ostream &OS,
- DWARFDataExtractor &rnglistData,
- DIDumpOptions DumpOpts) {
+static void
+dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) {
uint32_t Offset = 0;
while (rnglistData.isValidOffset(Offset)) {
llvm::DWARFDebugRnglistTable Rnglists;
@@ -297,16 +287,36 @@ static void dumpRnglistsSection(raw_ostream &OS,
break;
Offset = TableOffset + Length;
} else {
- Rnglists.dump(OS, DumpOpts);
+ Rnglists.dump(OS, LookupPooledAddress, DumpOpts);
}
}
}
+static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+ DWARFDataExtractor Data,
+ const MCRegisterInfo *MRI,
+ Optional<uint64_t> DumpOffset) {
+ uint32_t Offset = 0;
+ DWARFDebugLoclists Loclists;
+
+ DWARFListTableHeader Header(".debug_loclists", "locations");
+ if (Error E = Header.extract(Data, &Offset)) {
+ WithColor::error() << toString(std::move(E)) << '\n';
+ return;
+ }
+
+ Header.dump(OS, DumpOpts);
+ DataExtractor LocData(Data.getData().drop_front(Offset),
+ Data.isLittleEndian(), Header.getAddrSize());
+
+ Loclists.parse(LocData, Header.getVersion());
+ Loclists.dump(OS, 0, MRI, DumpOffset);
+}
+
void DWARFContext::dump(
raw_ostream &OS, DIDumpOptions DumpOpts,
std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
- Optional<uint64_t> DumpOffset;
uint64_t DumpType = DumpOpts.DumpType;
StringRef Extension = sys::path::extension(DObj->getFileName());
@@ -323,13 +333,13 @@ void DWARFContext::dump(
bool Explicit = DumpType != DIDT_All && !IsDWO;
bool ExplicitDWO = Explicit && IsDWO;
auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
- StringRef Section) {
- DumpOffset = DumpOffsets[ID];
+ StringRef Section) -> Optional<uint64_t> * {
unsigned Mask = 1U << ID;
bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
- if (Should)
- OS << "\n" << Name << " contents:\n";
- return Should;
+ if (!Should)
+ return nullptr;
+ OS << "\n" << Name << " contents:\n";
+ return &DumpOffsets[ID];
};
// Dump individual sections.
@@ -340,57 +350,63 @@ void DWARFContext::dump(
DObj->getAbbrevDWOSection()))
getDebugAbbrevDWO()->dump(OS);
- auto dumpDebugInfo = [&](bool IsExplicit, const char *Name,
- DWARFSection Section, cu_iterator_range CUs) {
- if (shouldDump(IsExplicit, Name, DIDT_ID_DebugInfo, Section.Data)) {
- if (DumpOffset)
- getDIEForOffset(DumpOffset.getValue())
+ auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
+ OS << '\n' << Name << " contents:\n";
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
+ for (const auto &U : Units)
+ U->getDIEForOffset(DumpOffset.getValue())
.dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- for (const auto &CU : CUs)
- CU->dump(OS, DumpOpts);
- }
+ else
+ for (const auto &U : Units)
+ U->dump(OS, DumpOpts);
};
- dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
- compile_units());
- dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
- dwo_compile_units());
+ if ((DumpType & DIDT_DebugInfo)) {
+ if (Explicit || getNumCompileUnits())
+ dumpDebugInfo(".debug_info", info_section_units());
+ if (ExplicitDWO || getNumDWOCompileUnits())
+ dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
+ }
- auto dumpDebugType = [&](const char *Name,
- tu_section_iterator_range TUSections) {
+ auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
OS << '\n' << Name << " contents:\n";
- DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
- for (const auto &TUS : TUSections)
- for (const auto &TU : TUS)
- if (DumpOffset)
- TU->getDIEForOffset(*DumpOffset)
- .dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- TU->dump(OS, DumpOpts);
+ for (const auto &U : Units)
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
+ U->getDIEForOffset(*DumpOffset)
+ .dump(OS, 0, DumpOpts.noImplicitRecursion());
+ else
+ U->dump(OS, DumpOpts);
};
if ((DumpType & DIDT_DebugTypes)) {
if (Explicit || getNumTypeUnits())
- dumpDebugType(".debug_types", type_unit_sections());
+ dumpDebugType(".debug_types", types_section_units());
if (ExplicitDWO || getNumDWOTypeUnits())
- dumpDebugType(".debug_types.dwo", dwo_type_unit_sections());
+ dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
- if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
- DObj->getLocSection().Data)) {
- getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
+ DObj->getLocSection().Data)) {
+ getDebugLoc()->dump(OS, getRegisterInfo(), *Off);
+ }
+ if (const auto *Off =
+ shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
+ DObj->getLoclistsSection().Data)) {
+ DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
+ 0);
+ dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off);
}
- if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
- DObj->getLocDWOSection().Data)) {
- getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
+ DObj->getLocDWOSection().Data)) {
+ getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off);
}
- if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
- DObj->getDebugFrameSection()))
- getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
+ DObj->getDebugFrameSection()))
+ getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
- if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
- DObj->getEHFrameSection()))
- getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
+ DObj->getEHFrameSection()))
+ getEHFrame()->dump(OS, getRegisterInfo(), *Off);
if (DumpType & DIDT_DebugMacro) {
if (Explicit || !getDebugMacro()->empty()) {
@@ -409,38 +425,41 @@ void DWARFContext::dump(
}
auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
- DIDumpOptions DumpOpts) {
+ DIDumpOptions DumpOpts,
+ Optional<uint64_t> DumpOffset) {
while (!Parser.done()) {
if (DumpOffset && Parser.getOffset() != *DumpOffset) {
- Parser.skip();
+ Parser.skip(dumpWarning);
continue;
}
OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
if (DumpOpts.Verbose) {
- Parser.parseNext(DWARFDebugLine::warn, DWARFDebugLine::warn, &OS);
+ Parser.parseNext(dumpWarning, dumpWarning, &OS);
} else {
- DWARFDebugLine::LineTable LineTable = Parser.parseNext();
+ DWARFDebugLine::LineTable LineTable =
+ Parser.parseNext(dumpWarning, dumpWarning);
LineTable.dump(OS, DumpOpts);
}
}
};
- if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
- DObj->getLineSection().Data)) {
+ if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
+ DObj->getLineSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
0);
DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
- type_unit_sections());
- DumpLineSection(Parser, DumpOpts);
+ type_units());
+ DumpLineSection(Parser, DumpOpts, *Off);
}
- if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
- DObj->getLineDWOSection().Data)) {
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
+ DObj->getLineDWOSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
isLittleEndian(), 0);
DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
- dwo_type_unit_sections());
- DumpLineSection(Parser, DumpOpts);
+ dwo_type_units());
+ DumpLineSection(Parser, DumpOpts, *Off);
}
if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
@@ -509,56 +528,64 @@ void DWARFContext::dump(
}
}
+ auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
+ const auto &CUs = compile_units();
+ auto I = CUs.begin();
+ if (I == CUs.end())
+ return None;
+ return (*I)->getAddrOffsetSectionItem(Index);
+ };
+
if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
DObj->getRnglistsSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
DObj->getRnglistsDWOSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
- DObj->getPubNamesSection()))
- DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
+ DObj->getPubNamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
- DObj->getPubTypesSection()))
- DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
+ DObj->getPubTypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
- DObj->getGnuPubNamesSection()))
- DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
+ DObj->getGnuPubNamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
- DObj->getGnuPubTypesSection()))
- DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
+ DObj->getGnuPubTypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
DObj->getStringOffsetSection().Data))
- dumpStringOffsetsSection(
- OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
- DObj->getStringSection(), compile_units(), type_unit_sections(),
- isLittleEndian(), getMaxVersion());
+ dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
+ DObj->getStringOffsetSection(),
+ DObj->getStringSection(), normal_units(),
+ isLittleEndian(), getMaxVersion());
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
DObj->getStringOffsetDWOSection().Data))
- dumpStringOffsetsSection(
- OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
- DObj->getStringDWOSection(), dwo_compile_units(),
- dwo_type_unit_sections(), isLittleEndian(), getMaxVersion());
+ dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
+ DObj->getStringOffsetDWOSection(),
+ DObj->getStringDWOSection(), dwo_units(),
+ isLittleEndian(), getMaxDWOVersion());
- if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
+ if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
DObj->getGdbIndexSection())) {
getGdbIndex().dump(OS);
}
@@ -584,11 +611,12 @@ void DWARFContext::dump(
}
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
- DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), true);
+ parseDWOUnits(LazyParse);
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
- return DWOCUs.getUnitForIndexEntry(*R);
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
@@ -607,14 +635,14 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
continue;
}
if (DWOCU->getDWOId() == Hash)
- return DWOCU.get();
+ return dyn_cast<DWARFCompileUnit>(DWOCU.get());
}
return nullptr;
}
DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
- parseCompileUnits();
- if (auto *CU = CUs.getUnitForOffset(Offset))
+ parseNormalUnits();
+ if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
return DWARFDie();
}
@@ -690,26 +718,28 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
return Loc.get();
Loc.reset(new DWARFDebugLoc);
- // Assume all compile units have the same address byte size.
+ // Assume all units have the same address byte size.
if (getNumCompileUnits()) {
DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
- getCompileUnitAtIndex(0)->getAddressByteSize());
+ getUnitAtIndex(0)->getAddressByteSize());
Loc->parse(LocData);
}
return Loc.get();
}
-const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
+const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
if (LocDWO)
return LocDWO.get();
- LocDWO.reset(new DWARFDebugLocDWO());
+ LocDWO.reset(new DWARFDebugLoclists());
// Assume all compile units have the same address byte size.
- if (getNumCompileUnits()) {
- DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(),
- getCompileUnitAtIndex(0)->getAddressByteSize());
- LocDWO->parse(LocData);
- }
+ // FIXME: We don't need AddressSize for split DWARF since relocatable
+ // addresses cannot appear there. At the moment DWARFExpression requires it.
+ DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
+ // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
+ // that means we are parsing the new style .debug_loc (pre-standatized version
+ // of the .debug_loclists).
+ LocDWO->parse(LocData, 4 /* Version */);
return LocDWO.get();
}
@@ -737,7 +767,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
isLittleEndian(), DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
@@ -748,7 +778,7 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
@@ -806,9 +836,9 @@ const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
const DWARFDebugLine::LineTable *
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
- getLineTableForUnit(U, DWARFDebugLine::warn);
+ getLineTableForUnit(U, dumpWarning);
if (!ExpectedLineTable) {
- DWARFDebugLine::warn(ExpectedLineTable.takeError());
+ dumpWarning(ExpectedLineTable.takeError());
return nullptr;
}
return *ExpectedLineTable;
@@ -843,35 +873,34 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
RecoverableErrorCallback);
}
-void DWARFContext::parseCompileUnits() {
- CUs.parse(*this, DObj->getInfoSection());
-}
-
-void DWARFContext::parseTypeUnits() {
- if (!TUs.empty())
+void DWARFContext::parseNormalUnits() {
+ if (!NormalUnits.empty())
return;
+ DObj->forEachInfoSections([&](const DWARFSection &S) {
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
+ });
+ NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
- TUs.emplace_back();
- TUs.back().parse(*this, S);
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
});
}
-void DWARFContext::parseDWOCompileUnits() {
- DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
-}
-
-void DWARFContext::parseDWOTypeUnits() {
- if (!DWOTUs.empty())
+void DWARFContext::parseDWOUnits(bool Lazy) {
+ if (!DWOUnits.empty())
return;
+ DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
+ });
+ DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOTUs.emplace_back();
- DWOTUs.back().parseDWO(*this, S);
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
});
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
- parseCompileUnits();
- return CUs.getUnitForOffset(Offset);
+ parseNormalUnits();
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ NormalUnits.getUnitForOffset(Offset));
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
@@ -1213,19 +1242,20 @@ class DWARFObjInMemory final : public DWARFObject {
const object::ObjectFile *Obj = nullptr;
std::vector<SectionName> SectionNames;
- using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
+ using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
std::map<object::SectionRef, unsigned>>;
- TypeSectionMap TypesSections;
- TypeSectionMap TypesDWOSections;
+ InfoSectionMap InfoSections;
+ InfoSectionMap TypesSections;
+ InfoSectionMap InfoDWOSections;
+ InfoSectionMap TypesDWOSections;
- DWARFSectionMap InfoSection;
DWARFSectionMap LocSection;
+ DWARFSectionMap LocListsSection;
DWARFSectionMap LineSection;
DWARFSectionMap RangeSection;
DWARFSectionMap RnglistsSection;
DWARFSectionMap StringOffsetSection;
- DWARFSectionMap InfoDWOSection;
DWARFSectionMap LineDWOSection;
DWARFSectionMap LocDWOSection;
DWARFSectionMap StringOffsetDWOSection;
@@ -1237,16 +1267,19 @@ class DWARFObjInMemory final : public DWARFObject {
DWARFSectionMap AppleNamespacesSection;
DWARFSectionMap AppleObjCSection;
DWARFSectionMap DebugNamesSection;
+ DWARFSectionMap PubNamesSection;
+ DWARFSectionMap PubTypesSection;
+ DWARFSectionMap GnuPubNamesSection;
+ DWARFSectionMap GnuPubTypesSection;
DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
return StringSwitch<DWARFSectionMap *>(Name)
- .Case("debug_info", &InfoSection)
.Case("debug_loc", &LocSection)
+ .Case("debug_loclists", &LocListsSection)
.Case("debug_line", &LineSection)
.Case("debug_str_offsets", &StringOffsetSection)
.Case("debug_ranges", &RangeSection)
.Case("debug_rnglists", &RnglistsSection)
- .Case("debug_info.dwo", &InfoDWOSection)
.Case("debug_loc.dwo", &LocDWOSection)
.Case("debug_line.dwo", &LineDWOSection)
.Case("debug_names", &DebugNamesSection)
@@ -1254,6 +1287,10 @@ class DWARFObjInMemory final : public DWARFObject {
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
.Case("apple_names", &AppleNamesSection)
+ .Case("debug_pubnames", &PubNamesSection)
+ .Case("debug_pubtypes", &PubTypesSection)
+ .Case("debug_gnu_pubnames", &GnuPubNamesSection)
+ .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
.Case("apple_types", &AppleTypesSection)
.Case("apple_namespaces", &AppleNamespacesSection)
.Case("apple_namespac", &AppleNamespacesSection)
@@ -1267,12 +1304,8 @@ class DWARFObjInMemory final : public DWARFObject {
StringRef EHFrameSection;
StringRef StringSection;
StringRef MacinfoSection;
- StringRef PubNamesSection;
- StringRef PubTypesSection;
- StringRef GnuPubNamesSection;
StringRef AbbrevDWOSection;
StringRef StringDWOSection;
- StringRef GnuPubTypesSection;
StringRef CUIndexSection;
StringRef GdbIndexSection;
StringRef TUIndexSection;
@@ -1292,10 +1325,6 @@ class DWARFObjInMemory final : public DWARFObject {
.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)
@@ -1335,6 +1364,16 @@ public:
for (const auto &SecIt : Sections) {
if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
*SectionData = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info")
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
+ InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info.dwo")
+ InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types")
+ TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types.dwo")
+ TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
}
}
DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
@@ -1389,9 +1428,13 @@ public:
// FIXME: Use the other dwo range section when we emit it.
RangeDWOSection.Data = Data;
}
+ } else if (Name == "debug_info") {
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
+ InfoSections[Section].Data = Data;
+ } else if (Name == "debug_info.dwo") {
+ InfoDWOSections[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;
@@ -1426,9 +1469,16 @@ public:
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")
+ // Find debug_info and debug_types relocs by section rather than name
+ // as there are multiple, comdat grouped, of these sections.
+ if (RelSecName == "debug_info")
+ Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_info.dwo")
+ Map = &static_cast<DWARFSectionMap &>(
+ InfoDWOSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_types")
Map =
&static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
.Relocs;
@@ -1526,8 +1576,10 @@ public:
StringRef getLineStringSection() const override { return LineStringSection; }
// Sections for DWARF5 split dwarf proposal.
- const DWARFSection &getInfoDWOSection() const override {
- return InfoDWOSection;
+ void forEachInfoDWOSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoDWOSections)
+ F(P.second);
}
void forEachTypesDWOSections(
function_ref<void(const DWARFSection &)> F) const override {
@@ -1537,6 +1589,7 @@ public:
StringRef getAbbrevSection() const override { return AbbrevSection; }
const DWARFSection &getLocSection() const override { return LocSection; }
+ const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
StringRef getARangeSection() const override { return ARangeSection; }
StringRef getDebugFrameSection() const override { return DebugFrameSection; }
StringRef getEHFrameSection() const override { return EHFrameSection; }
@@ -1547,12 +1600,12 @@ public:
return RnglistsSection;
}
StringRef getMacinfoSection() const override { return MacinfoSection; }
- StringRef getPubNamesSection() const override { return PubNamesSection; }
- StringRef getPubTypesSection() const override { return PubTypesSection; }
- StringRef getGnuPubNamesSection() const override {
+ const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
+ const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
+ const DWARFSection &getGnuPubNamesSection() const override {
return GnuPubNamesSection;
}
- StringRef getGnuPubTypesSection() const override {
+ const DWARFSection &getGnuPubTypesSection() const override {
return GnuPubTypesSection;
}
const DWARFSection &getAppleNamesSection() const override {
@@ -1573,7 +1626,11 @@ public:
StringRef getFileName() const override { return FileName; }
uint8_t getAddressSize() const override { return AddressSize; }
- const DWARFSection &getInfoSection() const override { return InfoSection; }
+ void forEachInfoSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoSections)
+ F(P.second);
+ }
void forEachTypesSections(
function_ref<void(const DWARFSection &)> F) const override {
for (auto &P : TypesSections)
@@ -1609,7 +1666,8 @@ Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
const Target *TheTarget =
TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
if (!TargetLookupError.empty())
- return make_error<StringError>(TargetLookupError, inconvertibleErrorCode());
+ return createStringError(errc::invalid_argument,
+ TargetLookupError.c_str());
RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
return Error::success();
}
@@ -1627,3 +1685,9 @@ uint8_t DWARFContext::getCUAddrSize() {
}
return Addr;
}
+
+void DWARFContext::dumpWarning(Error Warning) {
+ handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
+ WithColor::warning() << Info.message() << '\n';
+ });
+}