summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp623
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp11
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp3
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp30
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp39
5 files changed, 442 insertions, 264 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()) {
OpenPOWER on IntegriCloud