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