Don't use 'using std::error_code' in include/llvm.
[oota-llvm.git] / lib / DebugInfo / 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 "DWARFContext.h"
11 #include "DWARFDebugArangeSet.h"
12
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/Support/Compression.h"
16 #include "llvm/Support/Dwarf.h"
17 #include "llvm/Support/Format.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <algorithm>
21 using namespace llvm;
22 using namespace dwarf;
23 using namespace object;
24 using std::error_code;
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 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
64   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
65     OS << ".debug_abbrev contents:\n";
66     getDebugAbbrev()->dump(OS);
67   }
68
69   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
70     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
71       OS << "\n.debug_abbrev.dwo contents:\n";
72       D->dump(OS);
73     }
74
75   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
76     OS << "\n.debug_info contents:\n";
77     for (const auto &CU : compile_units())
78       CU->dump(OS);
79   }
80
81   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
82       getNumDWOCompileUnits()) {
83     OS << "\n.debug_info.dwo contents:\n";
84     for (const auto &DWOCU : dwo_compile_units())
85       DWOCU->dump(OS);
86   }
87
88   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
89     OS << "\n.debug_types contents:\n";
90     for (const auto &TU : type_units())
91       TU->dump(OS);
92   }
93
94   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
95       getNumDWOTypeUnits()) {
96     OS << "\n.debug_types.dwo contents:\n";
97     for (const auto &DWOTU : dwo_type_units())
98       DWOTU->dump(OS);
99   }
100
101   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
102     OS << "\n.debug_loc contents:\n";
103     getDebugLoc()->dump(OS);
104   }
105
106   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
107     OS << "\n.debug_loc.dwo contents:\n";
108     getDebugLocDWO()->dump(OS);
109   }
110
111   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
112     OS << "\n.debug_frame contents:\n";
113     getDebugFrame()->dump(OS);
114   }
115
116   uint32_t offset = 0;
117   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
118     OS << "\n.debug_aranges contents:\n";
119     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
120     DWARFDebugArangeSet set;
121     while (set.extract(arangesData, &offset))
122       set.dump(OS);
123   }
124
125   uint8_t savedAddressByteSize = 0;
126   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
127     OS << "\n.debug_line contents:\n";
128     for (const auto &CU : compile_units()) {
129       savedAddressByteSize = CU->getAddressByteSize();
130       unsigned stmtOffset =
131           CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
132               CU.get(), DW_AT_stmt_list, -1U);
133       if (stmtOffset != -1U) {
134         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
135                                savedAddressByteSize);
136         DWARFDebugLine::LineTable LineTable;
137         LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
138         LineTable.dump(OS);
139       }
140     }
141   }
142
143   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
144     OS << "\n.debug_line.dwo contents:\n";
145     unsigned stmtOffset = 0;
146     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
147                            savedAddressByteSize);
148     DWARFDebugLine::LineTable LineTable;
149     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
150       LineTable.dump(OS);
151       LineTable.clear();
152     }
153   }
154
155   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
156     OS << "\n.debug_str contents:\n";
157     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
158     offset = 0;
159     uint32_t strOffset = 0;
160     while (const char *s = strData.getCStr(&offset)) {
161       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
162       strOffset = offset;
163     }
164   }
165
166   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
167       !getStringDWOSection().empty()) {
168     OS << "\n.debug_str.dwo contents:\n";
169     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
170     offset = 0;
171     uint32_t strDWOOffset = 0;
172     while (const char *s = strDWOData.getCStr(&offset)) {
173       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
174       strDWOOffset = offset;
175     }
176   }
177
178   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
179     OS << "\n.debug_ranges contents:\n";
180     // In fact, different compile units may have different address byte
181     // sizes, but for simplicity we just use the address byte size of the last
182     // compile unit (there is no easy and fast way to associate address range
183     // list and the compile unit it describes).
184     DataExtractor rangesData(getRangeSection(), isLittleEndian(),
185                              savedAddressByteSize);
186     offset = 0;
187     DWARFDebugRangeList rangeList;
188     while (rangeList.extract(rangesData, &offset))
189       rangeList.dump(OS);
190   }
191
192   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
193     dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
194                    isLittleEndian(), false);
195
196   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
197     dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
198                    isLittleEndian(), false);
199
200   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
201     dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
202                    isLittleEndian(), true /* GnuStyle */);
203
204   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
205     dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
206                    isLittleEndian(), true /* GnuStyle */);
207
208   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
209       !getStringOffsetDWOSection().empty()) {
210     OS << "\n.debug_str_offsets.dwo contents:\n";
211     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
212                                0);
213     offset = 0;
214     uint64_t size = getStringOffsetDWOSection().size();
215     while (offset < size) {
216       OS << format("0x%8.8x: ", offset);
217       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
218     }
219   }
220 }
221
222 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
223   if (Abbrev)
224     return Abbrev.get();
225
226   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
227
228   Abbrev.reset(new DWARFDebugAbbrev());
229   Abbrev->extract(abbrData);
230   return Abbrev.get();
231 }
232
233 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
234   if (AbbrevDWO)
235     return AbbrevDWO.get();
236
237   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
238   AbbrevDWO.reset(new DWARFDebugAbbrev());
239   AbbrevDWO->extract(abbrData);
240   return AbbrevDWO.get();
241 }
242
243 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
244   if (Loc)
245     return Loc.get();
246
247   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
248   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
249   // assume all compile units have the same address byte size
250   if (getNumCompileUnits())
251     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
252   return Loc.get();
253 }
254
255 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
256   if (LocDWO)
257     return LocDWO.get();
258
259   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
260   LocDWO.reset(new DWARFDebugLocDWO());
261   LocDWO->parse(LocData);
262   return LocDWO.get();
263 }
264
265 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
266   if (Aranges)
267     return Aranges.get();
268
269   Aranges.reset(new DWARFDebugAranges());
270   Aranges->generate(this);
271   return Aranges.get();
272 }
273
274 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
275   if (DebugFrame)
276     return DebugFrame.get();
277
278   // There's a "bug" in the DWARFv3 standard with respect to the target address
279   // size within debug frame sections. While DWARF is supposed to be independent
280   // of its container, FDEs have fields with size being "target address size",
281   // which isn't specified in DWARF in general. It's only specified for CUs, but
282   // .eh_frame can appear without a .debug_info section. Follow the example of
283   // other tools (libdwarf) and extract this from the container (ObjectFile
284   // provides this information). This problem is fixed in DWARFv4
285   // See this dwarf-discuss discussion for more details:
286   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
287   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
288                                getAddressSize());
289   DebugFrame.reset(new DWARFDebugFrame());
290   DebugFrame->parse(debugFrameData);
291   return DebugFrame.get();
292 }
293
294 const DWARFLineTable *
295 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
296   if (!Line)
297     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
298
299   unsigned stmtOffset =
300       cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
301           cu, DW_AT_stmt_list, -1U);
302   if (stmtOffset == -1U)
303     return nullptr; // No line table for this compile unit.
304
305   // See if the line table is cached.
306   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
307     return lt;
308
309   // We have to parse it first.
310   DataExtractor lineData(getLineSection().Data, isLittleEndian(),
311                          cu->getAddressByteSize());
312   return Line->getOrParseLineTable(lineData, stmtOffset);
313 }
314
315 void DWARFContext::parseCompileUnits() {
316   if (!CUs.empty())
317     return;
318   uint32_t offset = 0;
319   const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
320                                               isLittleEndian(), 0);
321   while (DIData.isValidOffset(offset)) {
322     std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
323         getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
324         getStringSection(), StringRef(), getAddrSection(),
325         &getInfoSection().Relocs, isLittleEndian()));
326     if (!CU->extract(DIData, &offset)) {
327       break;
328     }
329     CUs.push_back(std::move(CU));
330     offset = CUs.back()->getNextUnitOffset();
331   }
332 }
333
334 void DWARFContext::parseTypeUnits() {
335   if (!TUs.empty())
336     return;
337   for (const auto &I : getTypesSections()) {
338     uint32_t offset = 0;
339     const DataExtractor &DIData =
340         DataExtractor(I.second.Data, isLittleEndian(), 0);
341     while (DIData.isValidOffset(offset)) {
342       std::unique_ptr<DWARFTypeUnit> TU(
343           new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(),
344                             getStringSection(), StringRef(), getAddrSection(),
345                             &I.second.Relocs, isLittleEndian()));
346       if (!TU->extract(DIData, &offset))
347         break;
348       TUs.push_back(std::move(TU));
349       offset = TUs.back()->getNextUnitOffset();
350     }
351   }
352 }
353
354 void DWARFContext::parseDWOCompileUnits() {
355   if (!DWOCUs.empty())
356     return;
357   uint32_t offset = 0;
358   const DataExtractor &DIData =
359       DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
360   while (DIData.isValidOffset(offset)) {
361     std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
362         getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
363         getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
364         &getInfoDWOSection().Relocs, isLittleEndian()));
365     if (!DWOCU->extract(DIData, &offset)) {
366       break;
367     }
368     DWOCUs.push_back(std::move(DWOCU));
369     offset = DWOCUs.back()->getNextUnitOffset();
370   }
371 }
372
373 void DWARFContext::parseDWOTypeUnits() {
374   if (!DWOTUs.empty())
375     return;
376   for (const auto &I : getTypesDWOSections()) {
377     uint32_t offset = 0;
378     const DataExtractor &DIData =
379         DataExtractor(I.second.Data, isLittleEndian(), 0);
380     while (DIData.isValidOffset(offset)) {
381       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
382           getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
383           getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
384           &I.second.Relocs, isLittleEndian()));
385       if (!TU->extract(DIData, &offset))
386         break;
387       DWOTUs.push_back(std::move(TU));
388       offset = DWOTUs.back()->getNextUnitOffset();
389     }
390   }
391 }
392
393 namespace {
394   struct OffsetComparator {
395
396     bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
397                     const std::unique_ptr<DWARFCompileUnit> &RHS) const {
398       return LHS->getOffset() < RHS->getOffset();
399     }
400     bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
401                     uint32_t RHS) const {
402       return LHS->getOffset() < RHS;
403     }
404     bool operator()(uint32_t LHS,
405                     const std::unique_ptr<DWARFCompileUnit> &RHS) const {
406       return LHS < RHS->getOffset();
407     }
408   };
409 }
410
411 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
412   parseCompileUnits();
413
414   std::unique_ptr<DWARFCompileUnit> *CU =
415       std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
416   if (CU != CUs.end()) {
417     return CU->get();
418   }
419   return nullptr;
420 }
421
422 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
423   // First, get the offset of the compile unit.
424   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
425   // Retrieve the compile unit.
426   return getCompileUnitForOffset(CUOffset);
427 }
428
429 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
430                                       const DWARFLineTable *LineTable,
431                                       uint64_t FileIndex, FileLineInfoKind Kind,
432                                       std::string &FileName) {
433   if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
434       !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
435     return false;
436   if (Kind == FileLineInfoKind::AbsoluteFilePath &&
437       sys::path::is_relative(FileName)) {
438     // We may still need to append compilation directory of compile unit.
439     SmallString<16> AbsolutePath;
440     if (const char *CompilationDir = CU->getCompilationDir()) {
441       sys::path::append(AbsolutePath, CompilationDir);
442     }
443     sys::path::append(AbsolutePath, FileName);
444     FileName = AbsolutePath.str();
445   }
446   return true;
447 }
448
449 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
450                                           const DWARFLineTable *LineTable,
451                                           uint64_t Address,
452                                           FileLineInfoKind Kind,
453                                           DILineInfo &Result) {
454   if (!CU || !LineTable)
455     return false;
456   // Get the index of row we're looking for in the line table.
457   uint32_t RowIndex = LineTable->lookupAddress(Address);
458   if (RowIndex == -1U)
459     return false;
460   // Take file number and line/column from the row.
461   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
462   if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
463                                  Result.FileName))
464     return false;
465   Result.Line = Row.Line;
466   Result.Column = Row.Column;
467   return true;
468 }
469
470 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
471                                       FunctionNameKind Kind,
472                                       std::string &FunctionName) {
473   if (Kind == FunctionNameKind::None)
474     return false;
475   // The address may correspond to instruction in some inlined function,
476   // so we have to build the chain of inlined functions and take the
477   // name of the topmost function in it.
478   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
479       CU->getInlinedChainForAddress(Address);
480   if (InlinedChain.DIEs.size() == 0)
481     return false;
482   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
483   if (const char *Name =
484           TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
485     FunctionName = Name;
486     return true;
487   }
488   return false;
489 }
490
491 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
492                                                DILineInfoSpecifier Spec) {
493   DILineInfo Result;
494
495   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
496   if (!CU)
497     return Result;
498   getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
499   if (Spec.FLIKind != FileLineInfoKind::None) {
500     const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
501     getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
502   }
503   return Result;
504 }
505
506 DILineInfoTable
507 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
508                                          DILineInfoSpecifier Spec) {
509   DILineInfoTable  Lines;
510   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
511   if (!CU)
512     return Lines;
513
514   std::string FunctionName = "<invalid>";
515   getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
516
517   // If the Specifier says we don't need FileLineInfo, just
518   // return the top-most function at the starting address.
519   if (Spec.FLIKind == FileLineInfoKind::None) {
520     DILineInfo Result;
521     Result.FunctionName = FunctionName;
522     Lines.push_back(std::make_pair(Address, Result));
523     return Lines;
524   }
525
526   const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
527
528   // Get the index of row we're looking for in the line table.
529   std::vector<uint32_t> RowVector;
530   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
531     return Lines;
532
533   for (uint32_t RowIndex : RowVector) {
534     // Take file number and line/column from the row.
535     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
536     DILineInfo Result;
537     getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
538                               Result.FileName);
539     Result.FunctionName = FunctionName;
540     Result.Line = Row.Line;
541     Result.Column = Row.Column;
542     Lines.push_back(std::make_pair(Row.Address, Result));
543   }
544
545   return Lines;
546 }
547
548 DIInliningInfo
549 DWARFContext::getInliningInfoForAddress(uint64_t Address,
550                                         DILineInfoSpecifier Spec) {
551   DIInliningInfo InliningInfo;
552
553   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
554   if (!CU)
555     return InliningInfo;
556
557   const DWARFLineTable *LineTable = nullptr;
558   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
559       CU->getInlinedChainForAddress(Address);
560   if (InlinedChain.DIEs.size() == 0) {
561     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
562     // try to at least get file/line info from symbol table.
563     if (Spec.FLIKind != FileLineInfoKind::None) {
564       DILineInfo Frame;
565       LineTable = getLineTableForCompileUnit(CU);
566       if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
567                                         Frame)) {
568         InliningInfo.addFrame(Frame);
569       }
570     }
571     return InliningInfo;
572   }
573
574   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
575   for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
576     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
577     DILineInfo Frame;
578     // Get function name if necessary.
579     if (const char *Name =
580             FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
581       Frame.FunctionName = Name;
582     if (Spec.FLIKind != FileLineInfoKind::None) {
583       if (i == 0) {
584         // For the topmost frame, initialize the line table of this
585         // compile unit and fetch file/line info from it.
586         LineTable = getLineTableForCompileUnit(CU);
587         // For the topmost routine, get file/line info from line table.
588         getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
589                                       Frame);
590       } else {
591         // Otherwise, use call file, call line and call column from
592         // previous DIE in inlined chain.
593         getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
594                                   Frame.FileName);
595         Frame.Line = CallLine;
596         Frame.Column = CallColumn;
597       }
598       // Get call file/line/column of a current DIE.
599       if (i + 1 < n) {
600         FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
601                                    CallColumn);
602       }
603     }
604     InliningInfo.addFrame(Frame);
605   }
606   return InliningInfo;
607 }
608
609 static bool consumeCompressedDebugSectionHeader(StringRef &data,
610                                                 uint64_t &OriginalSize) {
611   // Consume "ZLIB" prefix.
612   if (!data.startswith("ZLIB"))
613     return false;
614   data = data.substr(4);
615   // Consume uncompressed section size (big-endian 8 bytes).
616   DataExtractor extractor(data, false, 8);
617   uint32_t Offset = 0;
618   OriginalSize = extractor.getU64(&Offset);
619   if (Offset == 0)
620     return false;
621   data = data.substr(Offset);
622   return true;
623 }
624
625 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
626     : IsLittleEndian(Obj->isLittleEndian()),
627       AddressSize(Obj->getBytesInAddress()) {
628   for (const SectionRef &Section : Obj->sections()) {
629     StringRef name;
630     Section.getName(name);
631     StringRef data;
632     Section.getContents(data);
633
634     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
635
636     // Check if debug info section is compressed with zlib.
637     if (name.startswith("zdebug_")) {
638       uint64_t OriginalSize;
639       if (!zlib::isAvailable() ||
640           !consumeCompressedDebugSectionHeader(data, OriginalSize))
641         continue;
642       UncompressedSections.resize(UncompressedSections.size() + 1);
643       if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
644           zlib::StatusOK) {
645         UncompressedSections.pop_back();
646         continue;
647       }
648       // Make data point to uncompressed section contents and save its contents.
649       name = name.substr(1);
650       data = UncompressedSections.back();
651     }
652
653     StringRef *SectionData =
654         StringSwitch<StringRef *>(name)
655             .Case("debug_info", &InfoSection.Data)
656             .Case("debug_abbrev", &AbbrevSection)
657             .Case("debug_loc", &LocSection.Data)
658             .Case("debug_line", &LineSection.Data)
659             .Case("debug_aranges", &ARangeSection)
660             .Case("debug_frame", &DebugFrameSection)
661             .Case("debug_str", &StringSection)
662             .Case("debug_ranges", &RangeSection)
663             .Case("debug_pubnames", &PubNamesSection)
664             .Case("debug_pubtypes", &PubTypesSection)
665             .Case("debug_gnu_pubnames", &GnuPubNamesSection)
666             .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
667             .Case("debug_info.dwo", &InfoDWOSection.Data)
668             .Case("debug_abbrev.dwo", &AbbrevDWOSection)
669             .Case("debug_loc.dwo", &LocDWOSection.Data)
670             .Case("debug_line.dwo", &LineDWOSection.Data)
671             .Case("debug_str.dwo", &StringDWOSection)
672             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
673             .Case("debug_addr", &AddrSection)
674             // Any more debug info sections go here.
675             .Default(nullptr);
676     if (SectionData) {
677       *SectionData = data;
678       if (name == "debug_ranges") {
679         // FIXME: Use the other dwo range section when we emit it.
680         RangeDWOSection = data;
681       }
682     } else if (name == "debug_types") {
683       // Find debug_types data by section rather than name as there are
684       // multiple, comdat grouped, debug_types sections.
685       TypesSections[Section].Data = data;
686     } else if (name == "debug_types.dwo") {
687       TypesDWOSections[Section].Data = data;
688     }
689
690     section_iterator RelocatedSection = Section.getRelocatedSection();
691     if (RelocatedSection == Obj->section_end())
692       continue;
693
694     StringRef RelSecName;
695     RelocatedSection->getName(RelSecName);
696     RelSecName = RelSecName.substr(
697         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
698
699     // TODO: Add support for relocations in other sections as needed.
700     // Record relocations for the debug_info and debug_line sections.
701     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
702         .Case("debug_info", &InfoSection.Relocs)
703         .Case("debug_loc", &LocSection.Relocs)
704         .Case("debug_info.dwo", &InfoDWOSection.Relocs)
705         .Case("debug_line", &LineSection.Relocs)
706         .Default(nullptr);
707     if (!Map) {
708       // Find debug_types relocs by section rather than name as there are
709       // multiple, comdat grouped, debug_types sections.
710       if (RelSecName == "debug_types")
711         Map = &TypesSections[*RelocatedSection].Relocs;
712       else if (RelSecName == "debug_types.dwo")
713         Map = &TypesDWOSections[*RelocatedSection].Relocs;
714       else
715         continue;
716     }
717
718     if (Section.relocation_begin() != Section.relocation_end()) {
719       uint64_t SectionSize;
720       RelocatedSection->getSize(SectionSize);
721       for (const RelocationRef &Reloc : Section.relocations()) {
722         uint64_t Address;
723         Reloc.getOffset(Address);
724         uint64_t Type;
725         Reloc.getType(Type);
726         uint64_t SymAddr = 0;
727         // ELF relocations may need the symbol address
728         if (Obj->isELF()) {
729           object::symbol_iterator Sym = Reloc.getSymbol();
730           Sym->getAddress(SymAddr);
731         }
732
733         object::RelocVisitor V(Obj->getFileFormatName());
734         // The section address is always 0 for debug sections.
735         object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
736         if (V.error()) {
737           SmallString<32> Name;
738           error_code ec(Reloc.getTypeName(Name));
739           if (ec) {
740             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
741           }
742           errs() << "error: failed to compute relocation: "
743                  << Name << "\n";
744           continue;
745         }
746
747         if (Address + R.Width > SectionSize) {
748           errs() << "error: " << R.Width << "-byte relocation starting "
749                  << Address << " bytes into section " << name << " which is "
750                  << SectionSize << " bytes long.\n";
751           continue;
752         }
753         if (R.Width > 8) {
754           errs() << "error: can't handle a relocation of more than 8 bytes at "
755                     "a time.\n";
756           continue;
757         }
758         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
759                      << " at " << format("%p", Address)
760                      << " with width " << format("%d", R.Width)
761                      << "\n");
762         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
763       }
764     }
765   }
766 }
767
768 void DWARFContextInMemory::anchor() { }