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