1 //===- DWARFContext.cpp ---------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
16 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
17 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
28 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
29 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
30 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
31 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
32 #include "llvm/Object/Decompressor.h"
33 #include "llvm/Object/MachO.h"
34 #include "llvm/Object/ObjectFile.h"
35 #include "llvm/Object/RelocVisitor.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/DataExtractor.h"
38 #include "llvm/Support/Debug.h"
39 #include "llvm/Support/Error.h"
40 #include "llvm/Support/Format.h"
41 #include "llvm/Support/MemoryBuffer.h"
42 #include "llvm/Support/raw_ostream.h"
50 using namespace dwarf;
51 using namespace object;
53 #define DEBUG_TYPE "dwarf"
55 typedef DWARFDebugLine::LineTable DWARFLineTable;
56 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
57 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
59 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
60 const DWARFSection& Section, StringRef StringSection,
62 DataExtractor AccelSection(Section.Data, LittleEndian, 0);
63 DataExtractor StrData(StringSection, LittleEndian, 0);
64 OS << "\n." << Name << " contents:\n";
65 DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
71 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
72 bool SummarizeTypes) {
73 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
74 OS << ".debug_abbrev contents:\n";
75 getDebugAbbrev()->dump(OS);
78 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
79 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
80 OS << "\n.debug_abbrev.dwo contents:\n";
84 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
85 OS << "\n.debug_info contents:\n";
86 for (const auto &CU : compile_units())
90 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
91 getNumDWOCompileUnits()) {
92 OS << "\n.debug_info.dwo contents:\n";
93 for (const auto &DWOCU : dwo_compile_units())
97 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
98 OS << "\n.debug_types contents:\n";
99 for (const auto &TUS : type_unit_sections())
100 for (const auto &TU : TUS)
101 TU->dump(OS, SummarizeTypes);
104 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
105 getNumDWOTypeUnits()) {
106 OS << "\n.debug_types.dwo contents:\n";
107 for (const auto &DWOTUS : dwo_type_unit_sections())
108 for (const auto &DWOTU : DWOTUS)
109 DWOTU->dump(OS, SummarizeTypes);
112 if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
113 OS << "\n.debug_loc contents:\n";
114 getDebugLoc()->dump(OS);
117 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
118 OS << "\n.debug_loc.dwo contents:\n";
119 getDebugLocDWO()->dump(OS);
122 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
123 OS << "\n.debug_frame contents:\n";
124 getDebugFrame()->dump(OS);
126 OS << "\n.eh_frame contents:\n";
127 getEHFrame()->dump(OS);
131 if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
132 OS << "\n.debug_macinfo contents:\n";
133 getDebugMacro()->dump(OS);
137 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
138 OS << "\n.debug_aranges contents:\n";
139 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
140 DWARFDebugArangeSet set;
141 while (set.extract(arangesData, &offset))
145 uint8_t savedAddressByteSize = 0;
146 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
147 OS << "\n.debug_line contents:\n";
148 for (const auto &CU : compile_units()) {
149 savedAddressByteSize = CU->getAddressByteSize();
150 auto CUDIE = CU->getUnitDIE();
153 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
154 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
155 savedAddressByteSize);
156 DWARFDebugLine::LineTable LineTable;
157 uint32_t Offset = *StmtOffset;
158 LineTable.parse(lineData, &getLineSection().Relocs, &Offset);
164 if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
165 OS << "\n.debug_cu_index contents:\n";
166 getCUIndex().dump(OS);
169 if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
170 OS << "\n.debug_tu_index contents:\n";
171 getTUIndex().dump(OS);
174 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
175 OS << "\n.debug_line.dwo contents:\n";
176 unsigned stmtOffset = 0;
177 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
178 savedAddressByteSize);
179 DWARFDebugLine::LineTable LineTable;
180 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
186 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
187 OS << "\n.debug_str contents:\n";
188 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
190 uint32_t strOffset = 0;
191 while (const char *s = strData.getCStr(&offset)) {
192 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
197 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
198 !getStringDWOSection().empty()) {
199 OS << "\n.debug_str.dwo contents:\n";
200 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
202 uint32_t strDWOOffset = 0;
203 while (const char *s = strDWOData.getCStr(&offset)) {
204 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
205 strDWOOffset = offset;
209 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
210 OS << "\n.debug_ranges contents:\n";
211 // In fact, different compile units may have different address byte
212 // sizes, but for simplicity we just use the address byte size of the last
213 // compile unit (there is no easy and fast way to associate address range
214 // list and the compile unit it describes).
215 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
216 savedAddressByteSize);
218 DWARFDebugRangeList rangeList;
219 while (rangeList.extract(rangesData, &offset))
223 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
224 DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
225 .dump("debug_pubnames", OS);
227 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
228 DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
229 .dump("debug_pubtypes", OS);
231 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
232 DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
234 .dump("debug_gnu_pubnames", OS);
236 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
237 DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
239 .dump("debug_gnu_pubtypes", OS);
241 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
242 !getStringOffsetDWOSection().empty()) {
243 OS << "\n.debug_str_offsets.dwo contents:\n";
244 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
247 uint64_t size = getStringOffsetDWOSection().size();
248 while (offset < size) {
249 OS << format("0x%8.8x: ", offset);
250 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
254 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
255 !getGdbIndexSection().empty()) {
256 OS << "\n.gnu_index contents:\n";
257 getGdbIndex().dump(OS);
260 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
261 dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
262 getStringSection(), isLittleEndian());
264 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
265 dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
266 getStringSection(), isLittleEndian());
268 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
269 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
270 getStringSection(), isLittleEndian());
272 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
273 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
274 getStringSection(), isLittleEndian());
277 const DWARFUnitIndex &DWARFContext::getCUIndex() {
281 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
283 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
284 CUIndex->parse(CUIndexData);
288 const DWARFUnitIndex &DWARFContext::getTUIndex() {
292 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
294 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
295 TUIndex->parse(TUIndexData);
299 DWARFGdbIndex &DWARFContext::getGdbIndex() {
303 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
304 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
305 GdbIndex->parse(GdbIndexData);
309 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
313 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
315 Abbrev.reset(new DWARFDebugAbbrev());
316 Abbrev->extract(abbrData);
320 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
322 return AbbrevDWO.get();
324 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
325 AbbrevDWO.reset(new DWARFDebugAbbrev());
326 AbbrevDWO->extract(abbrData);
327 return AbbrevDWO.get();
330 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
334 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
335 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
336 // assume all compile units have the same address byte size
337 if (getNumCompileUnits())
338 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
342 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
346 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
347 LocDWO.reset(new DWARFDebugLocDWO());
348 LocDWO->parse(LocData);
352 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
354 return Aranges.get();
356 Aranges.reset(new DWARFDebugAranges());
357 Aranges->generate(this);
358 return Aranges.get();
361 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
363 return DebugFrame.get();
365 // There's a "bug" in the DWARFv3 standard with respect to the target address
366 // size within debug frame sections. While DWARF is supposed to be independent
367 // of its container, FDEs have fields with size being "target address size",
368 // which isn't specified in DWARF in general. It's only specified for CUs, but
369 // .eh_frame can appear without a .debug_info section. Follow the example of
370 // other tools (libdwarf) and extract this from the container (ObjectFile
371 // provides this information). This problem is fixed in DWARFv4
372 // See this dwarf-discuss discussion for more details:
373 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
374 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
376 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
377 DebugFrame->parse(debugFrameData);
378 return DebugFrame.get();
381 const DWARFDebugFrame *DWARFContext::getEHFrame() {
383 return EHFrame.get();
385 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
387 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
388 DebugFrame->parse(debugFrameData);
389 return DebugFrame.get();
392 const DWARFDebugMacro *DWARFContext::getDebugMacro() {
396 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
397 Macro.reset(new DWARFDebugMacro());
398 Macro->parse(MacinfoData);
402 const DWARFLineTable *
403 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
405 Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
407 auto UnitDIE = U->getUnitDIE();
411 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
413 return nullptr; // No line table for this compile unit.
415 uint32_t stmtOffset = *Offset + U->getLineTableOffset();
416 // See if the line table is cached.
417 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
420 // We have to parse it first.
421 DataExtractor lineData(U->getLineSection(), isLittleEndian(),
422 U->getAddressByteSize());
423 return Line->getOrParseLineTable(lineData, stmtOffset);
426 void DWARFContext::parseCompileUnits() {
427 CUs.parse(*this, getInfoSection());
430 void DWARFContext::parseTypeUnits() {
433 for (const auto &I : getTypesSections()) {
435 TUs.back().parse(*this, I.second);
439 void DWARFContext::parseDWOCompileUnits() {
440 DWOCUs.parseDWO(*this, getInfoDWOSection());
443 void DWARFContext::parseDWOTypeUnits() {
446 for (const auto &I : getTypesDWOSections()) {
447 DWOTUs.emplace_back();
448 DWOTUs.back().parseDWO(*this, I.second);
452 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
454 return CUs.getUnitForOffset(Offset);
457 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
458 // First, get the offset of the compile unit.
459 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
460 // Retrieve the compile unit.
461 return getCompileUnitForOffset(CUOffset);
464 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
466 FunctionNameKind Kind,
467 std::string &FunctionName,
468 uint32_t &StartLine) {
469 // The address may correspond to instruction in some inlined function,
470 // so we have to build the chain of inlined functions and take the
471 // name of the topmost function in it.
472 SmallVector<DWARFDie, 4> InlinedChain;
473 CU->getInlinedChainForAddress(Address, InlinedChain);
474 if (InlinedChain.empty())
477 const DWARFDie &DIE = InlinedChain[0];
478 bool FoundResult = false;
479 const char *Name = nullptr;
480 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
484 if (auto DeclLineResult = DIE.getDeclLine()) {
485 StartLine = DeclLineResult;
492 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
493 DILineInfoSpecifier Spec) {
496 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
499 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
502 if (Spec.FLIKind != FileLineInfoKind::None) {
503 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
504 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
505 Spec.FLIKind, Result);
511 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
512 DILineInfoSpecifier Spec) {
513 DILineInfoTable Lines;
514 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
518 std::string FunctionName = "<invalid>";
519 uint32_t StartLine = 0;
520 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
523 // If the Specifier says we don't need FileLineInfo, just
524 // return the top-most function at the starting address.
525 if (Spec.FLIKind == FileLineInfoKind::None) {
527 Result.FunctionName = FunctionName;
528 Result.StartLine = StartLine;
529 Lines.push_back(std::make_pair(Address, Result));
533 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
535 // Get the index of row we're looking for in the line table.
536 std::vector<uint32_t> RowVector;
537 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
540 for (uint32_t RowIndex : RowVector) {
541 // Take file number and line/column from the row.
542 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
544 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
545 Spec.FLIKind, Result.FileName);
546 Result.FunctionName = FunctionName;
547 Result.Line = Row.Line;
548 Result.Column = Row.Column;
549 Result.StartLine = StartLine;
550 Lines.push_back(std::make_pair(Row.Address, Result));
557 DWARFContext::getInliningInfoForAddress(uint64_t Address,
558 DILineInfoSpecifier Spec) {
559 DIInliningInfo InliningInfo;
561 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
565 const DWARFLineTable *LineTable = nullptr;
566 SmallVector<DWARFDie, 4> InlinedChain;
567 CU->getInlinedChainForAddress(Address, InlinedChain);
568 if (InlinedChain.size() == 0) {
569 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
570 // try to at least get file/line info from symbol table.
571 if (Spec.FLIKind != FileLineInfoKind::None) {
573 LineTable = getLineTableForUnit(CU);
575 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
576 Spec.FLIKind, Frame))
577 InliningInfo.addFrame(Frame);
582 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
583 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
584 DWARFDie &FunctionDIE = InlinedChain[i];
586 // Get function name if necessary.
587 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
588 Frame.FunctionName = Name;
589 if (auto DeclLineResult = FunctionDIE.getDeclLine())
590 Frame.StartLine = DeclLineResult;
591 if (Spec.FLIKind != FileLineInfoKind::None) {
593 // For the topmost frame, initialize the line table of this
594 // compile unit and fetch file/line info from it.
595 LineTable = getLineTableForUnit(CU);
596 // For the topmost routine, get file/line info from line table.
598 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
599 Spec.FLIKind, Frame);
601 // Otherwise, use call file, call line and call column from
602 // previous DIE in inlined chain.
604 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
605 Spec.FLIKind, Frame.FileName);
606 Frame.Line = CallLine;
607 Frame.Column = CallColumn;
608 Frame.Discriminator = CallDiscriminator;
610 // Get call file/line/column of a current DIE.
612 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
616 InliningInfo.addFrame(Frame);
621 static Error createError(const Twine &Reason, llvm::Error E) {
622 return make_error<StringError>(Reason + toString(std::move(E)),
623 inconvertibleErrorCode());
626 /// Returns the address of symbol relocation used against. Used for futher
627 /// relocations computation. Symbol's section load address is taken in account if
628 /// LoadedObjectInfo interface is provided.
629 static Expected<uint64_t> getSymbolAddress(const object::ObjectFile &Obj,
630 const RelocationRef &Reloc,
631 const LoadedObjectInfo *L) {
633 object::section_iterator RSec = Obj.section_end();
634 object::symbol_iterator Sym = Reloc.getSymbol();
636 // First calculate the address of the symbol or section as it appears
637 // in the object file
638 if (Sym != Obj.symbol_end()) {
639 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
641 return createError("error: failed to compute symbol address: ",
642 SymAddrOrErr.takeError());
644 // Also remember what section this symbol is in for later
645 auto SectOrErr = Sym->getSection();
647 return createError("error: failed to get symbol section: ",
648 SectOrErr.takeError());
652 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
653 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
654 Ret = RSec->getAddress();
657 // If we are given load addresses for the sections, we need to adjust:
658 // SymAddr = (Address of Symbol Or Section in File) -
659 // (Address of Section in File) +
660 // (Load Address of Section)
661 // RSec is now either the section being targeted or the section
662 // containing the symbol being targeted. In either case,
663 // we need to perform the same computation.
664 if (L && RSec != Obj.section_end())
665 if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
666 Ret += SectionLoadAddress - RSec->getAddress();
670 static bool isRelocScattered(const object::ObjectFile &Obj,
671 const RelocationRef &Reloc) {
672 const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
675 // MachO also has relocations that point to sections and
676 // scattered relocations.
677 auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
678 return MachObj->isRelocationScattered(RelocInfo);
681 DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
682 const LoadedObjectInfo *L)
683 : IsLittleEndian(Obj.isLittleEndian()),
684 AddressSize(Obj.getBytesInAddress()) {
685 for (const SectionRef &Section : Obj.sections()) {
687 Section.getName(name);
688 // Skip BSS and Virtual sections, they aren't interesting.
689 bool IsBSS = Section.isBSS();
692 bool IsVirtual = Section.isVirtual();
697 section_iterator RelocatedSection = Section.getRelocatedSection();
698 // Try to obtain an already relocated version of this section.
699 // Else use the unrelocated section from the object file. We'll have to
700 // apply relocations ourselves later.
701 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
702 Section.getContents(data);
704 if (Decompressor::isCompressed(Section)) {
705 Expected<Decompressor> Decompressor =
706 Decompressor::create(name, data, IsLittleEndian, AddressSize == 8);
710 if (auto Err = Decompressor->decompress(Out))
712 UncompressedSections.emplace_back(std::move(Out));
713 data = UncompressedSections.back();
716 // Compressed sections names in GNU style starts from ".z",
717 // at this point section is decompressed and we drop compression prefix.
719 name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
721 if (StringRef *SectionData = MapSectionToMember(name)) {
723 if (name == "debug_ranges") {
724 // FIXME: Use the other dwo range section when we emit it.
725 RangeDWOSection = data;
727 } else if (name == "debug_types") {
728 // Find debug_types data by section rather than name as there are
729 // multiple, comdat grouped, debug_types sections.
730 TypesSections[Section].Data = data;
731 } else if (name == "debug_types.dwo") {
732 TypesDWOSections[Section].Data = data;
735 if (RelocatedSection == Obj.section_end())
738 StringRef RelSecName;
739 StringRef RelSecData;
740 RelocatedSection->getName(RelSecName);
742 // If the section we're relocating was relocated already by the JIT,
743 // then we used the relocated version above, so we do not need to process
744 // relocations for it now.
745 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
748 // In Mach-o files, the relocations do not need to be applied if
749 // there is no load offset to apply. The value read at the
750 // relocation point already factors in the section address
751 // (actually applying the relocations will produce wrong results
752 // as the section address will be added twice).
753 if (!L && isa<MachOObjectFile>(&Obj))
756 RelSecName = RelSecName.substr(
757 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
759 // TODO: Add support for relocations in other sections as needed.
760 // Record relocations for the debug_info and debug_line sections.
761 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
762 .Case("debug_info", &InfoSection.Relocs)
763 .Case("debug_loc", &LocSection.Relocs)
764 .Case("debug_info.dwo", &InfoDWOSection.Relocs)
765 .Case("debug_line", &LineSection.Relocs)
766 .Case("apple_names", &AppleNamesSection.Relocs)
767 .Case("apple_types", &AppleTypesSection.Relocs)
768 .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
769 .Case("apple_namespac", &AppleNamespacesSection.Relocs)
770 .Case("apple_objc", &AppleObjCSection.Relocs)
773 // Find debug_types relocs by section rather than name as there are
774 // multiple, comdat grouped, debug_types sections.
775 if (RelSecName == "debug_types")
776 Map = &TypesSections[*RelocatedSection].Relocs;
777 else if (RelSecName == "debug_types.dwo")
778 Map = &TypesDWOSections[*RelocatedSection].Relocs;
783 if (Section.relocation_begin() != Section.relocation_end()) {
784 uint64_t SectionSize = RelocatedSection->getSize();
785 for (const RelocationRef &Reloc : Section.relocations()) {
786 // FIXME: it's not clear how to correctly handle scattered
788 if (isRelocScattered(Obj, Reloc))
791 Expected<uint64_t> SymAddrOrErr = getSymbolAddress(Obj, Reloc, L);
793 errs() << toString(SymAddrOrErr.takeError()) << '\n';
797 object::RelocVisitor V(Obj);
798 object::RelocToApply R(V.visit(Reloc.getType(), Reloc, *SymAddrOrErr));
800 SmallString<32> Name;
801 Reloc.getTypeName(Name);
802 errs() << "error: failed to compute relocation: "
806 uint64_t Address = Reloc.getOffset();
807 if (Address + R.Width > SectionSize) {
808 errs() << "error: " << R.Width << "-byte relocation starting "
809 << Address << " bytes into section " << name << " which is "
810 << SectionSize << " bytes long.\n";
814 errs() << "error: can't handle a relocation of more than 8 bytes at "
818 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
819 << " at " << format("%p", Address)
820 << " with width " << format("%d", R.Width)
822 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
828 DWARFContextInMemory::DWARFContextInMemory(
829 const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
831 : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
832 for (const auto &SecIt : Sections) {
833 if (StringRef *SectionData = MapSectionToMember(SecIt.first()))
834 *SectionData = SecIt.second->getBuffer();
838 StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
839 return StringSwitch<StringRef *>(Name)
840 .Case("debug_info", &InfoSection.Data)
841 .Case("debug_abbrev", &AbbrevSection)
842 .Case("debug_loc", &LocSection.Data)
843 .Case("debug_line", &LineSection.Data)
844 .Case("debug_aranges", &ARangeSection)
845 .Case("debug_frame", &DebugFrameSection)
846 .Case("eh_frame", &EHFrameSection)
847 .Case("debug_str", &StringSection)
848 .Case("debug_ranges", &RangeSection)
849 .Case("debug_macinfo", &MacinfoSection)
850 .Case("debug_pubnames", &PubNamesSection)
851 .Case("debug_pubtypes", &PubTypesSection)
852 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
853 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
854 .Case("debug_info.dwo", &InfoDWOSection.Data)
855 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
856 .Case("debug_loc.dwo", &LocDWOSection.Data)
857 .Case("debug_line.dwo", &LineDWOSection.Data)
858 .Case("debug_str.dwo", &StringDWOSection)
859 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
860 .Case("debug_addr", &AddrSection)
861 .Case("apple_names", &AppleNamesSection.Data)
862 .Case("apple_types", &AppleTypesSection.Data)
863 .Case("apple_namespaces", &AppleNamespacesSection.Data)
864 .Case("apple_namespac", &AppleNamespacesSection.Data)
865 .Case("apple_objc", &AppleObjCSection.Data)
866 .Case("debug_cu_index", &CUIndexSection)
867 .Case("debug_tu_index", &TUIndexSection)
868 .Case("gdb_index", &GdbIndexSection)
869 // Any more debug info sections go here.
873 void DWARFContextInMemory::anchor() {}