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