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