dwarfdump: Use the index to find the right abbrev offset in DWP files
[oota-llvm.git] / lib / DebugInfo / DWARF / DWARFContext.cpp
1 //===-- DWARFContext.cpp --------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
15 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
16 #include "llvm/Support/Compression.h"
17 #include "llvm/Support/Dwarf.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <algorithm>
22 using namespace llvm;
23 using namespace dwarf;
24 using namespace object;
25
26 #define DEBUG_TYPE "dwarf"
27
28 typedef DWARFDebugLine::LineTable DWARFLineTable;
29 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
30 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
31
32 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
33                            bool LittleEndian, bool GnuStyle) {
34   OS << "\n." << Name << " contents:\n";
35   DataExtractor pubNames(Data, LittleEndian, 0);
36   uint32_t offset = 0;
37   while (pubNames.isValidOffset(offset)) {
38     OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
39     OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
40     OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
41     OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
42     if (GnuStyle)
43       OS << "Offset     Linkage  Kind     Name\n";
44     else
45       OS << "Offset     Name\n";
46
47     while (offset < Data.size()) {
48       uint32_t dieRef = pubNames.getU32(&offset);
49       if (dieRef == 0)
50         break;
51       OS << format("0x%8.8x ", dieRef);
52       if (GnuStyle) {
53         PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
54         OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
55            << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
56            << ' ';
57       }
58       OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
59     }
60   }
61 }
62
63 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
64                              const DWARFSection& Section, StringRef StringSection,
65                              bool LittleEndian) {
66   DataExtractor AccelSection(Section.Data, LittleEndian, 0);
67   DataExtractor StrData(StringSection, LittleEndian, 0);
68   OS << "\n." << Name << " contents:\n";
69   DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
70   if (!Accel.extract())
71     return;
72   Accel.dump(OS);
73 }
74
75 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
76   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
77     OS << ".debug_abbrev contents:\n";
78     getDebugAbbrev()->dump(OS);
79   }
80
81   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
82     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
83       OS << "\n.debug_abbrev.dwo contents:\n";
84       D->dump(OS);
85     }
86
87   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
88     OS << "\n.debug_info contents:\n";
89     for (const auto &CU : compile_units())
90       CU->dump(OS);
91   }
92
93   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
94       getNumDWOCompileUnits()) {
95     OS << "\n.debug_info.dwo contents:\n";
96     for (const auto &DWOCU : dwo_compile_units())
97       DWOCU->dump(OS);
98   }
99
100   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
101     OS << "\n.debug_types contents:\n";
102     for (const auto &TUS : type_unit_sections())
103       for (const auto &TU : TUS)
104         TU->dump(OS);
105   }
106
107   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
108       getNumDWOTypeUnits()) {
109     OS << "\n.debug_types.dwo contents:\n";
110     for (const auto &DWOTUS : dwo_type_unit_sections())
111       for (const auto &DWOTU : DWOTUS)
112         DWOTU->dump(OS);
113   }
114
115   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
116     OS << "\n.debug_loc contents:\n";
117     getDebugLoc()->dump(OS);
118   }
119
120   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
121     OS << "\n.debug_loc.dwo contents:\n";
122     getDebugLocDWO()->dump(OS);
123   }
124
125   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
126     OS << "\n.debug_frame contents:\n";
127     getDebugFrame()->dump(OS);
128   }
129
130   if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
131     OS << "\n.debug_macinfo contents:\n";
132     getDebugMacro()->dump(OS);
133   }
134
135   uint32_t offset = 0;
136   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
137     OS << "\n.debug_aranges contents:\n";
138     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
139     DWARFDebugArangeSet set;
140     while (set.extract(arangesData, &offset))
141       set.dump(OS);
142   }
143
144   uint8_t savedAddressByteSize = 0;
145   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
146     OS << "\n.debug_line contents:\n";
147     for (const auto &CU : compile_units()) {
148       savedAddressByteSize = CU->getAddressByteSize();
149       const auto *CUDIE = CU->getUnitDIE();
150       if (CUDIE == nullptr)
151         continue;
152       unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
153           CU.get(), DW_AT_stmt_list, -1U);
154       if (stmtOffset != -1U) {
155         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
156                                savedAddressByteSize);
157         DWARFDebugLine::LineTable LineTable;
158         LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
159         LineTable.dump(OS);
160       }
161     }
162   }
163
164   if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
165     OS << "\n.debug_cu_index contents:\n";
166     DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(),
167                               savedAddressByteSize);
168     DWARFUnitIndex CUIndex;
169     if (CUIndex.parse(CUIndexData))
170       CUIndex.dump(OS);
171   }
172
173   if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
174     OS << "\n.debug_tu_index contents:\n";
175     DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(),
176                               savedAddressByteSize);
177     DWARFUnitIndex TUIndex;
178     if (TUIndex.parse(TUIndexData))
179       TUIndex.dump(OS);
180   }
181
182   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
183     OS << "\n.debug_line.dwo contents:\n";
184     unsigned stmtOffset = 0;
185     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
186                            savedAddressByteSize);
187     DWARFDebugLine::LineTable LineTable;
188     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
189       LineTable.dump(OS);
190       LineTable.clear();
191     }
192   }
193
194   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
195     OS << "\n.debug_str contents:\n";
196     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
197     offset = 0;
198     uint32_t strOffset = 0;
199     while (const char *s = strData.getCStr(&offset)) {
200       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
201       strOffset = offset;
202     }
203   }
204
205   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
206       !getStringDWOSection().empty()) {
207     OS << "\n.debug_str.dwo contents:\n";
208     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
209     offset = 0;
210     uint32_t strDWOOffset = 0;
211     while (const char *s = strDWOData.getCStr(&offset)) {
212       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
213       strDWOOffset = offset;
214     }
215   }
216
217   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
218     OS << "\n.debug_ranges contents:\n";
219     // In fact, different compile units may have different address byte
220     // sizes, but for simplicity we just use the address byte size of the last
221     // compile unit (there is no easy and fast way to associate address range
222     // list and the compile unit it describes).
223     DataExtractor rangesData(getRangeSection(), isLittleEndian(),
224                              savedAddressByteSize);
225     offset = 0;
226     DWARFDebugRangeList rangeList;
227     while (rangeList.extract(rangesData, &offset))
228       rangeList.dump(OS);
229   }
230
231   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
232     dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
233                    isLittleEndian(), false);
234
235   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
236     dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
237                    isLittleEndian(), false);
238
239   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
240     dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
241                    isLittleEndian(), true /* GnuStyle */);
242
243   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
244     dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
245                    isLittleEndian(), true /* GnuStyle */);
246
247   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
248       !getStringOffsetDWOSection().empty()) {
249     OS << "\n.debug_str_offsets.dwo contents:\n";
250     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
251                                0);
252     offset = 0;
253     uint64_t size = getStringOffsetDWOSection().size();
254     while (offset < size) {
255       OS << format("0x%8.8x: ", offset);
256       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
257     }
258   }
259
260   if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
261     dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
262                      getStringSection(), isLittleEndian());
263
264   if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
265     dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
266                      getStringSection(), isLittleEndian());
267
268   if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
269     dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
270                      getStringSection(), isLittleEndian());
271
272   if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
273     dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
274                      getStringSection(), isLittleEndian());
275 }
276
277 const DWARFUnitIndex &DWARFContext::getCUIndex() {
278   if (CUIndex)
279     return *CUIndex;
280
281   DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
282
283   CUIndex = llvm::make_unique<DWARFUnitIndex>();
284   CUIndex->parse(CUIndexData);
285   return *CUIndex;
286 }
287
288 const DWARFUnitIndex &DWARFContext::getTUIndex() {
289   if (TUIndex)
290     return *TUIndex;
291
292   DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
293
294   TUIndex = llvm::make_unique<DWARFUnitIndex>();
295   TUIndex->parse(TUIndexData);
296   return *TUIndex;
297 }
298
299 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
300   if (Abbrev)
301     return Abbrev.get();
302
303   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
304
305   Abbrev.reset(new DWARFDebugAbbrev());
306   Abbrev->extract(abbrData);
307   return Abbrev.get();
308 }
309
310 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
311   if (AbbrevDWO)
312     return AbbrevDWO.get();
313
314   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
315   AbbrevDWO.reset(new DWARFDebugAbbrev());
316   AbbrevDWO->extract(abbrData);
317   return AbbrevDWO.get();
318 }
319
320 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
321   if (Loc)
322     return Loc.get();
323
324   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
325   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
326   // assume all compile units have the same address byte size
327   if (getNumCompileUnits())
328     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
329   return Loc.get();
330 }
331
332 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
333   if (LocDWO)
334     return LocDWO.get();
335
336   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
337   LocDWO.reset(new DWARFDebugLocDWO());
338   LocDWO->parse(LocData);
339   return LocDWO.get();
340 }
341
342 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
343   if (Aranges)
344     return Aranges.get();
345
346   Aranges.reset(new DWARFDebugAranges());
347   Aranges->generate(this);
348   return Aranges.get();
349 }
350
351 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
352   if (DebugFrame)
353     return DebugFrame.get();
354
355   // There's a "bug" in the DWARFv3 standard with respect to the target address
356   // size within debug frame sections. While DWARF is supposed to be independent
357   // of its container, FDEs have fields with size being "target address size",
358   // which isn't specified in DWARF in general. It's only specified for CUs, but
359   // .eh_frame can appear without a .debug_info section. Follow the example of
360   // other tools (libdwarf) and extract this from the container (ObjectFile
361   // provides this information). This problem is fixed in DWARFv4
362   // See this dwarf-discuss discussion for more details:
363   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
364   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
365                                getAddressSize());
366   DebugFrame.reset(new DWARFDebugFrame());
367   DebugFrame->parse(debugFrameData);
368   return DebugFrame.get();
369 }
370
371 const DWARFDebugMacro *DWARFContext::getDebugMacro() {
372   if (Macro)
373     return Macro.get();
374
375   DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
376   Macro.reset(new DWARFDebugMacro());
377   Macro->parse(MacinfoData);
378   return Macro.get();
379 }
380
381 const DWARFLineTable *
382 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
383   if (!Line)
384     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
385   const auto *UnitDIE = U->getUnitDIE();
386   if (UnitDIE == nullptr)
387     return nullptr;
388   unsigned stmtOffset =
389       UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
390   if (stmtOffset == -1U)
391     return nullptr; // No line table for this compile unit.
392
393   // See if the line table is cached.
394   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
395     return lt;
396
397   // We have to parse it first.
398   DataExtractor lineData(getLineSection().Data, isLittleEndian(),
399                          U->getAddressByteSize());
400   return Line->getOrParseLineTable(lineData, stmtOffset);
401 }
402
403 void DWARFContext::parseCompileUnits() {
404   CUs.parse(*this, getInfoSection());
405 }
406
407 void DWARFContext::parseTypeUnits() {
408   if (!TUs.empty())
409     return;
410   for (const auto &I : getTypesSections()) {
411     TUs.emplace_back();
412     TUs.back().parse(*this, I.second);
413   }
414 }
415
416 void DWARFContext::parseDWOCompileUnits() {
417   DWOCUs.parseDWO(*this, getInfoDWOSection());
418 }
419
420 void DWARFContext::parseDWOTypeUnits() {
421   if (!DWOTUs.empty())
422     return;
423   for (const auto &I : getTypesDWOSections()) {
424     DWOTUs.emplace_back();
425     DWOTUs.back().parseDWO(*this, I.second);
426   }
427 }
428
429 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
430   parseCompileUnits();
431   return CUs.getUnitForOffset(Offset);
432 }
433
434 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
435   // First, get the offset of the compile unit.
436   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
437   // Retrieve the compile unit.
438   return getCompileUnitForOffset(CUOffset);
439 }
440
441 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
442                                       FunctionNameKind Kind,
443                                       std::string &FunctionName) {
444   if (Kind == FunctionNameKind::None)
445     return false;
446   // The address may correspond to instruction in some inlined function,
447   // so we have to build the chain of inlined functions and take the
448   // name of the topmost function in it.
449   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
450       CU->getInlinedChainForAddress(Address);
451   if (InlinedChain.DIEs.size() == 0)
452     return false;
453   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
454   if (const char *Name =
455           TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
456     FunctionName = Name;
457     return true;
458   }
459   return false;
460 }
461
462 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
463                                                DILineInfoSpecifier Spec) {
464   DILineInfo Result;
465
466   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
467   if (!CU)
468     return Result;
469   getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
470   if (Spec.FLIKind != FileLineInfoKind::None) {
471     if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
472       LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
473                                            Spec.FLIKind, Result);
474   }
475   return Result;
476 }
477
478 DILineInfoTable
479 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
480                                          DILineInfoSpecifier Spec) {
481   DILineInfoTable  Lines;
482   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
483   if (!CU)
484     return Lines;
485
486   std::string FunctionName = "<invalid>";
487   getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
488
489   // If the Specifier says we don't need FileLineInfo, just
490   // return the top-most function at the starting address.
491   if (Spec.FLIKind == FileLineInfoKind::None) {
492     DILineInfo Result;
493     Result.FunctionName = FunctionName;
494     Lines.push_back(std::make_pair(Address, Result));
495     return Lines;
496   }
497
498   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
499
500   // Get the index of row we're looking for in the line table.
501   std::vector<uint32_t> RowVector;
502   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
503     return Lines;
504
505   for (uint32_t RowIndex : RowVector) {
506     // Take file number and line/column from the row.
507     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
508     DILineInfo Result;
509     LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
510                                   Spec.FLIKind, Result.FileName);
511     Result.FunctionName = FunctionName;
512     Result.Line = Row.Line;
513     Result.Column = Row.Column;
514     Lines.push_back(std::make_pair(Row.Address, Result));
515   }
516
517   return Lines;
518 }
519
520 DIInliningInfo
521 DWARFContext::getInliningInfoForAddress(uint64_t Address,
522                                         DILineInfoSpecifier Spec) {
523   DIInliningInfo InliningInfo;
524
525   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
526   if (!CU)
527     return InliningInfo;
528
529   const DWARFLineTable *LineTable = nullptr;
530   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
531       CU->getInlinedChainForAddress(Address);
532   if (InlinedChain.DIEs.size() == 0) {
533     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
534     // try to at least get file/line info from symbol table.
535     if (Spec.FLIKind != FileLineInfoKind::None) {
536       DILineInfo Frame;
537       LineTable = getLineTableForUnit(CU);
538       if (LineTable &&
539           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
540                                                Spec.FLIKind, Frame))
541         InliningInfo.addFrame(Frame);
542     }
543     return InliningInfo;
544   }
545
546   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
547   for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
548     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
549     DILineInfo Frame;
550     // Get function name if necessary.
551     if (const char *Name =
552             FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
553       Frame.FunctionName = Name;
554     if (Spec.FLIKind != FileLineInfoKind::None) {
555       if (i == 0) {
556         // For the topmost frame, initialize the line table of this
557         // compile unit and fetch file/line info from it.
558         LineTable = getLineTableForUnit(CU);
559         // For the topmost routine, get file/line info from line table.
560         if (LineTable)
561           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
562                                                Spec.FLIKind, Frame);
563       } else {
564         // Otherwise, use call file, call line and call column from
565         // previous DIE in inlined chain.
566         if (LineTable)
567           LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
568                                         Spec.FLIKind, Frame.FileName);
569         Frame.Line = CallLine;
570         Frame.Column = CallColumn;
571       }
572       // Get call file/line/column of a current DIE.
573       if (i + 1 < n) {
574         FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
575                                    CallColumn);
576       }
577     }
578     InliningInfo.addFrame(Frame);
579   }
580   return InliningInfo;
581 }
582
583 static bool consumeCompressedDebugSectionHeader(StringRef &data,
584                                                 uint64_t &OriginalSize) {
585   // Consume "ZLIB" prefix.
586   if (!data.startswith("ZLIB"))
587     return false;
588   data = data.substr(4);
589   // Consume uncompressed section size (big-endian 8 bytes).
590   DataExtractor extractor(data, false, 8);
591   uint32_t Offset = 0;
592   OriginalSize = extractor.getU64(&Offset);
593   if (Offset == 0)
594     return false;
595   data = data.substr(Offset);
596   return true;
597 }
598
599 DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
600     const LoadedObjectInfo *L)
601     : IsLittleEndian(Obj.isLittleEndian()),
602       AddressSize(Obj.getBytesInAddress()) {
603   for (const SectionRef &Section : Obj.sections()) {
604     StringRef name;
605     Section.getName(name);
606     // Skip BSS and Virtual sections, they aren't interesting.
607     bool IsBSS = Section.isBSS();
608     if (IsBSS)
609       continue;
610     bool IsVirtual = Section.isVirtual();
611     if (IsVirtual)
612       continue;
613     StringRef data;
614
615     section_iterator RelocatedSection = Section.getRelocatedSection();
616     // Try to obtain an already relocated version of this section.
617     // Else use the unrelocated section from the object file. We'll have to
618     // apply relocations ourselves later.
619     if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
620       Section.getContents(data);
621
622     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
623
624     // Check if debug info section is compressed with zlib.
625     if (name.startswith("zdebug_")) {
626       uint64_t OriginalSize;
627       if (!zlib::isAvailable() ||
628           !consumeCompressedDebugSectionHeader(data, OriginalSize))
629         continue;
630       UncompressedSections.resize(UncompressedSections.size() + 1);
631       if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
632           zlib::StatusOK) {
633         UncompressedSections.pop_back();
634         continue;
635       }
636       // Make data point to uncompressed section contents and save its contents.
637       name = name.substr(1);
638       data = UncompressedSections.back();
639     }
640
641     StringRef *SectionData =
642         StringSwitch<StringRef *>(name)
643             .Case("debug_info", &InfoSection.Data)
644             .Case("debug_abbrev", &AbbrevSection)
645             .Case("debug_loc", &LocSection.Data)
646             .Case("debug_line", &LineSection.Data)
647             .Case("debug_aranges", &ARangeSection)
648             .Case("debug_frame", &DebugFrameSection)
649             .Case("debug_str", &StringSection)
650             .Case("debug_ranges", &RangeSection)
651             .Case("debug_macinfo", &MacinfoSection)
652             .Case("debug_pubnames", &PubNamesSection)
653             .Case("debug_pubtypes", &PubTypesSection)
654             .Case("debug_gnu_pubnames", &GnuPubNamesSection)
655             .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
656             .Case("debug_info.dwo", &InfoDWOSection.Data)
657             .Case("debug_abbrev.dwo", &AbbrevDWOSection)
658             .Case("debug_loc.dwo", &LocDWOSection.Data)
659             .Case("debug_line.dwo", &LineDWOSection.Data)
660             .Case("debug_str.dwo", &StringDWOSection)
661             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
662             .Case("debug_addr", &AddrSection)
663             .Case("apple_names", &AppleNamesSection.Data)
664             .Case("apple_types", &AppleTypesSection.Data)
665             .Case("apple_namespaces", &AppleNamespacesSection.Data)
666             .Case("apple_namespac", &AppleNamespacesSection.Data)
667             .Case("apple_objc", &AppleObjCSection.Data)
668             .Case("debug_cu_index", &CUIndexSection)
669             .Case("debug_tu_index", &TUIndexSection)
670             // Any more debug info sections go here.
671             .Default(nullptr);
672     if (SectionData) {
673       *SectionData = data;
674       if (name == "debug_ranges") {
675         // FIXME: Use the other dwo range section when we emit it.
676         RangeDWOSection = data;
677       }
678     } else if (name == "debug_types") {
679       // Find debug_types data by section rather than name as there are
680       // multiple, comdat grouped, debug_types sections.
681       TypesSections[Section].Data = data;
682     } else if (name == "debug_types.dwo") {
683       TypesDWOSections[Section].Data = data;
684     }
685
686     if (RelocatedSection == Obj.section_end())
687       continue;
688
689     StringRef RelSecName;
690     StringRef RelSecData;
691     RelocatedSection->getName(RelSecName);
692
693     // If the section we're relocating was relocated already by the JIT,
694     // then we used the relocated version above, so we do not need to process
695     // relocations for it now.
696     if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
697       continue;
698
699     // In Mach-o files, the relocations do not need to be applied if
700     // there is no load offset to apply. The value read at the
701     // relocation point already factors in the section address
702     // (actually applying the relocations will produce wrong results
703     // as the section address will be added twice).
704     if (!L && dyn_cast<MachOObjectFile>(&Obj))
705       continue;
706
707     RelSecName = RelSecName.substr(
708         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
709
710     // TODO: Add support for relocations in other sections as needed.
711     // Record relocations for the debug_info and debug_line sections.
712     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
713         .Case("debug_info", &InfoSection.Relocs)
714         .Case("debug_loc", &LocSection.Relocs)
715         .Case("debug_info.dwo", &InfoDWOSection.Relocs)
716         .Case("debug_line", &LineSection.Relocs)
717         .Case("apple_names", &AppleNamesSection.Relocs)
718         .Case("apple_types", &AppleTypesSection.Relocs)
719         .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
720         .Case("apple_namespac", &AppleNamespacesSection.Relocs)
721         .Case("apple_objc", &AppleObjCSection.Relocs)
722         .Default(nullptr);
723     if (!Map) {
724       // Find debug_types relocs by section rather than name as there are
725       // multiple, comdat grouped, debug_types sections.
726       if (RelSecName == "debug_types")
727         Map = &TypesSections[*RelocatedSection].Relocs;
728       else if (RelSecName == "debug_types.dwo")
729         Map = &TypesDWOSections[*RelocatedSection].Relocs;
730       else
731         continue;
732     }
733
734     if (Section.relocation_begin() != Section.relocation_end()) {
735       uint64_t SectionSize = RelocatedSection->getSize();
736       for (const RelocationRef &Reloc : Section.relocations()) {
737         uint64_t Address = Reloc.getOffset();
738         uint64_t Type = Reloc.getType();
739         uint64_t SymAddr = 0;
740         uint64_t SectionLoadAddress = 0;
741         object::symbol_iterator Sym = Reloc.getSymbol();
742         object::section_iterator RSec = Obj.section_end();
743
744         // First calculate the address of the symbol or section as it appears
745         // in the objct file
746         if (Sym != Obj.symbol_end()) {
747           ErrorOr<uint64_t> SymAddrOrErr = Sym->getAddress();
748           if (std::error_code EC = SymAddrOrErr.getError()) {
749             errs() << "error: failed to compute symbol address: "
750                    << EC.message() << '\n';
751             continue;
752           }
753           SymAddr = *SymAddrOrErr;
754           // Also remember what section this symbol is in for later
755           RSec = *Sym->getSection();
756         } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
757           // MachO also has relocations that point to sections and
758           // scattered relocations.
759           auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
760           if (MObj->isRelocationScattered(RelocInfo)) {
761             // FIXME: it's not clear how to correctly handle scattered
762             // relocations.
763             continue;
764           } else {
765             RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
766             SymAddr = RSec->getAddress();
767           }
768         }
769
770         // If we are given load addresses for the sections, we need to adjust:
771         // SymAddr = (Address of Symbol Or Section in File) -
772         //           (Address of Section in File) +
773         //           (Load Address of Section)
774         if (L != nullptr && RSec != Obj.section_end()) {
775           // RSec is now either the section being targeted or the section
776           // containing the symbol being targeted. In either case,
777           // we need to perform the same computation.
778           StringRef SecName;
779           RSec->getName(SecName);
780 //           llvm::dbgs() << "Name: '" << SecName
781 //                        << "', RSec: " << RSec->getRawDataRefImpl()
782 //                        << ", Section: " << Section.getRawDataRefImpl() << "\n";
783           SectionLoadAddress = L->getSectionLoadAddress(*RSec);
784           if (SectionLoadAddress != 0)
785             SymAddr += SectionLoadAddress - RSec->getAddress();
786         }
787
788         object::RelocVisitor V(Obj);
789         object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
790         if (V.error()) {
791           SmallString<32> Name;
792           Reloc.getTypeName(Name);
793           errs() << "error: failed to compute relocation: "
794                  << Name << "\n";
795           continue;
796         }
797
798         if (Address + R.Width > SectionSize) {
799           errs() << "error: " << R.Width << "-byte relocation starting "
800                  << Address << " bytes into section " << name << " which is "
801                  << SectionSize << " bytes long.\n";
802           continue;
803         }
804         if (R.Width > 8) {
805           errs() << "error: can't handle a relocation of more than 8 bytes at "
806                     "a time.\n";
807           continue;
808         }
809         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
810                      << " at " << format("%p", Address)
811                      << " with width " << format("%d", R.Width)
812                      << "\n");
813         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
814       }
815     }
816   }
817 }
818
819 void DWARFContextInMemory::anchor() { }