LLVM  6.0.0svn
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/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
34 #include "llvm/MC/MCRegisterInfo.h"
36 #include "llvm/Object/MachO.h"
37 #include "llvm/Object/ObjectFile.h"
39 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/Error.h"
42 #include "llvm/Support/Format.h"
44 #include "llvm/Support/Path.h"
47 #include <algorithm>
48 #include <cstdint>
49 #include <map>
50 #include <string>
51 #include <utility>
52 #include <vector>
53 
54 using namespace llvm;
55 using namespace dwarf;
56 using namespace object;
57 
58 #define DEBUG_TYPE "dwarf"
59 
63 
64 DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
65  std::string DWPName)
66  : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {}
67 
68 DWARFContext::~DWARFContext() = default;
69 
70 /// Dump the UUID load command.
71 static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
72  auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
73  if (!MachO)
74  return;
75  for (auto LC : MachO->load_commands()) {
77  if (LC.C.cmd == MachO::LC_UUID) {
78  if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
79  OS << "error: UUID load command is too short.\n";
80  return;
81  }
82  OS << "UUID: ";
83  memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
84  OS.write_uuid(UUID);
85  OS << ' ' << MachO->getFileFormatName();
86  OS << ' ' << MachO->getFileName() << '\n';
87  }
88  }
89 }
90 
91 static void
93  const DWARFObject &Obj,
94  const DWARFSection &StringOffsetsSection,
95  StringRef StringSection, bool LittleEndian) {
96  DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
97  uint32_t Offset = 0;
98  uint64_t SectionSize = StringOffsetsSection.Data.size();
99 
100  while (Offset < SectionSize) {
101  unsigned Version = 0;
103  unsigned EntrySize = 4;
104  // Perform validation and extract the segment size from the header.
105  if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
106  OS << "error: invalid contribution to string offsets table in section ."
107  << SectionName << ".\n";
108  return;
109  }
110  uint32_t ContributionStart = Offset;
111  uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
112  // A contribution size of 0xffffffff indicates DWARF64, with the actual size
113  // in the following 8 bytes. Otherwise, the DWARF standard mandates that
114  // the contribution size must be at most 0xfffffff0.
115  if (ContributionSize == 0xffffffff) {
116  if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
117  OS << "error: invalid contribution to string offsets table in section ."
118  << SectionName << ".\n";
119  return;
120  }
121  Format = DWARF64;
122  EntrySize = 8;
123  ContributionSize = StrOffsetExt.getU64(&Offset);
124  } else if (ContributionSize > 0xfffffff0) {
125  OS << "error: invalid contribution to string offsets table in section ."
126  << SectionName << ".\n";
127  return;
128  }
129 
130  // We must ensure that we don't read a partial record at the end, so we
131  // validate for a multiple of EntrySize. Also, we're expecting a version
132  // number and padding, which adds an additional 4 bytes.
133  uint64_t ValidationSize =
134  4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
135  if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
136  OS << "error: contribution to string offsets table in section ."
137  << SectionName << " has invalid length.\n";
138  return;
139  }
140 
141  Version = StrOffsetExt.getU16(&Offset);
142  Offset += 2;
143  OS << format("0x%8.8x: ", ContributionStart);
144  OS << "Contribution size = " << ContributionSize
145  << ", Version = " << Version << "\n";
146 
147  uint32_t ContributionBase = Offset;
148  DataExtractor StrData(StringSection, LittleEndian, 0);
149  while (Offset - ContributionBase < ContributionSize) {
150  OS << format("0x%8.8x: ", Offset);
151  // FIXME: We can only extract strings in DWARF32 format at the moment.
152  uint64_t StringOffset =
153  StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
154  if (Format == DWARF32) {
155  uint32_t StringOffset32 = (uint32_t)StringOffset;
156  OS << format("%8.8x ", StringOffset32);
157  const char *S = StrData.getCStr(&StringOffset32);
158  if (S)
159  OS << format("\"%s\"", S);
160  } else
161  OS << format("%16.16" PRIx64 " ", StringOffset);
162  OS << "\n";
163  }
164  }
165 }
166 
167 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
168 // string offsets section, where each compile or type unit contributes a
169 // number of entries (string offsets), with each contribution preceded by
170 // a header containing size and version number. Alternatively, it may be a
171 // monolithic series of string offsets, as generated by the pre-DWARF v5
172 // implementation of split DWARF.
174  const DWARFObject &Obj,
175  const DWARFSection &StringOffsetsSection,
176  StringRef StringSection, bool LittleEndian,
177  unsigned MaxVersion) {
178  // If we have at least one (compile or type) unit with DWARF v5 or greater,
179  // we assume that the section is formatted like a DWARF v5 string offsets
180  // section.
181  if (MaxVersion >= 5)
182  dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
183  StringSection, LittleEndian);
184  else {
185  DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
186  uint32_t offset = 0;
187  uint64_t size = StringOffsetsSection.Data.size();
188  // Ensure that size is a multiple of the size of an entry.
189  if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
190  OS << "error: size of ." << SectionName << " is not a multiple of "
191  << sizeof(uint32_t) << ".\n";
192  size &= -(uint64_t)sizeof(uint32_t);
193  }
194  DataExtractor StrData(StringSection, LittleEndian, 0);
195  while (offset < size) {
196  OS << format("0x%8.8x: ", offset);
197  uint32_t StringOffset = strOffsetExt.getU32(&offset);
198  OS << format("%8.8x ", StringOffset);
199  const char *S = StrData.getCStr(&StringOffset);
200  if (S)
201  OS << format("\"%s\"", S);
202  OS << "\n";
203  }
204  }
205 }
206 
208  raw_ostream &OS, DIDumpOptions DumpOpts,
209  std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
210 
211  Optional<uint64_t> DumpOffset;
212  uint64_t DumpType = DumpOpts.DumpType;
213 
214  StringRef Extension = sys::path::extension(DObj->getFileName());
215  bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
216 
217  // Print UUID header.
218  const auto *ObjFile = DObj->getFile();
219  if (DumpType & DIDT_UUID)
220  dumpUUID(OS, *ObjFile);
221 
222  // Print a header for each explicitly-requested section.
223  // Otherwise just print one for non-empty sections.
224  // Only print empty .dwo section headers when dumping a .dwo file.
225  bool Explicit = DumpType != DIDT_All && !IsDWO;
226  bool ExplicitDWO = Explicit && IsDWO;
227  auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
228  StringRef Section) {
229  DumpOffset = DumpOffsets[ID];
230  unsigned Mask = 1U << ID;
231  bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
232  if (Should)
233  OS << "\n" << Name << " contents:\n";
234  return Should;
235  };
236 
237  // Dump individual sections.
238  if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
239  DObj->getAbbrevSection()))
240  getDebugAbbrev()->dump(OS);
241  if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
242  DObj->getAbbrevDWOSection()))
243  getDebugAbbrevDWO()->dump(OS);
244 
245  auto dumpDebugInfo = [&](bool IsExplicit, const char *Name,
247  if (shouldDump(IsExplicit, Name, DIDT_ID_DebugInfo, Section.Data)) {
248  if (DumpOffset)
249  getDIEForOffset(DumpOffset.getValue())
250  .dump(OS, 0, DumpOpts.noImplicitRecursion());
251  else
252  for (const auto &CU : CUs)
253  CU->dump(OS, DumpOpts);
254  }
255  };
256  dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
257  compile_units());
258  dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
260 
261  auto dumpDebugType = [&](const char *Name,
262  tu_section_iterator_range TUSections) {
263  OS << '\n' << Name << " contents:\n";
264  DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
265  for (const auto &TUS : TUSections)
266  for (const auto &TU : TUS)
267  if (DumpOffset)
268  TU->getDIEForOffset(*DumpOffset)
269  .dump(OS, 0, DumpOpts.noImplicitRecursion());
270  else
271  TU->dump(OS, DumpOpts);
272  };
273  if ((DumpType & DIDT_DebugTypes)) {
274  if (Explicit || getNumTypeUnits())
275  dumpDebugType(".debug_types", type_unit_sections());
276  if (ExplicitDWO || getNumDWOTypeUnits())
277  dumpDebugType(".debug_types.dwo", dwo_type_unit_sections());
278  }
279 
280  if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
281  DObj->getLocSection().Data)) {
282  getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
283  }
284  if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
285  DObj->getLocDWOSection().Data)) {
286  getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset);
287  }
288 
289  if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
290  DObj->getDebugFrameSection()))
291  getDebugFrame()->dump(OS, DumpOffset);
292 
293  if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
294  DObj->getEHFrameSection()))
295  getEHFrame()->dump(OS, DumpOffset);
296 
297  if (DumpType & DIDT_DebugMacro) {
298  if (Explicit || !getDebugMacro()->empty()) {
299  OS << "\n.debug_macinfo contents:\n";
300  getDebugMacro()->dump(OS);
301  }
302  }
303 
304  if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
305  DObj->getARangeSection())) {
306  uint32_t offset = 0;
307  DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
309  while (set.extract(arangesData, &offset))
310  set.dump(OS);
311  }
312 
313  uint8_t savedAddressByteSize = 0;
314  if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
315  DObj->getLineSection().Data)) {
316  for (const auto &CU : compile_units()) {
317  savedAddressByteSize = CU->getAddressByteSize();
318  auto CUDIE = CU->getUnitDIE();
319  if (!CUDIE)
320  continue;
321  if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
322  if (DumpOffset && *StmtOffset != *DumpOffset)
323  continue;
324  DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
325  isLittleEndian(), savedAddressByteSize);
326  DWARFDebugLine::LineTable LineTable;
327  uint32_t Offset = *StmtOffset;
328  // Verbose dumping is done during parsing and not on the intermediate
329  // representation.
330  OS << "debug_line[" << format("0x%8.8x", Offset) << "]\n";
331  if (DumpOpts.Verbose) {
332  LineTable.parse(lineData, &Offset, &*CU, &OS);
333  } else {
334  LineTable.parse(lineData, &Offset, &*CU);
335  LineTable.dump(OS);
336  }
337  }
338  }
339  }
340 
341  // FIXME: This seems sketchy.
342  for (const auto &CU : compile_units()) {
343  savedAddressByteSize = CU->getAddressByteSize();
344  break;
345  }
346  if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
347  DObj->getLineDWOSection().Data)) {
348  unsigned stmtOffset = 0;
349  DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
350  isLittleEndian(), savedAddressByteSize);
351  DWARFDebugLine::LineTable LineTable;
352  while (LineTable.Prologue.parse(lineData, &stmtOffset, nullptr)) {
353  LineTable.dump(OS);
354  LineTable.clear();
355  }
356  }
357 
358  if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
359  DObj->getCUIndexSection())) {
360  getCUIndex().dump(OS);
361  }
362 
363  if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
364  DObj->getTUIndexSection())) {
365  getTUIndex().dump(OS);
366  }
367 
368  if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
369  DObj->getStringSection())) {
370  DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
371  uint32_t offset = 0;
372  uint32_t strOffset = 0;
373  while (const char *s = strData.getCStr(&offset)) {
374  OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
375  strOffset = offset;
376  }
377  }
378  if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
379  DObj->getStringDWOSection())) {
380  DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
381  uint32_t offset = 0;
382  uint32_t strDWOOffset = 0;
383  while (const char *s = strDWOData.getCStr(&offset)) {
384  OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
385  strDWOOffset = offset;
386  }
387  }
388 
389  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
390  DObj->getRangeSection().Data)) {
391  // In fact, different compile units may have different address byte
392  // sizes, but for simplicity we just use the address byte size of the
393  // last compile unit (there is no easy and fast way to associate address
394  // range list and the compile unit it describes).
395  // FIXME: savedAddressByteSize seems sketchy.
396  DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
397  isLittleEndian(), savedAddressByteSize);
398  uint32_t offset = 0;
399  DWARFDebugRangeList rangeList;
400  while (rangeList.extract(rangesData, &offset))
401  rangeList.dump(OS);
402  }
403 
404  if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
405  DObj->getPubNamesSection()))
406  DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
407  .dump(OS);
408 
409  if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
410  DObj->getPubTypesSection()))
411  DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
412  .dump(OS);
413 
414  if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
415  DObj->getGnuPubNamesSection()))
416  DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
417  true /* GnuStyle */)
418  .dump(OS);
419 
420  if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
421  DObj->getGnuPubTypesSection()))
422  DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
423  true /* GnuStyle */)
424  .dump(OS);
425 
426  if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
427  DObj->getStringOffsetSection().Data))
429  OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
430  DObj->getStringSection(), isLittleEndian(), getMaxVersion());
431  if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
432  DObj->getStringOffsetDWOSection().Data))
434  OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
435  DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
436 
437  if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
438  DObj->getGdbIndexSection())) {
439  getGdbIndex().dump(OS);
440  }
441 
442  if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
443  DObj->getAppleNamesSection().Data))
444  getAppleNames().dump(OS);
445 
446  if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
447  DObj->getAppleTypesSection().Data))
448  getAppleTypes().dump(OS);
449 
450  if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
451  DObj->getAppleNamespacesSection().Data))
452  getAppleNamespaces().dump(OS);
453 
454  if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
455  DObj->getAppleObjCSection().Data))
456  getAppleObjC().dump(OS);
457 }
458 
460  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), true);
461 
462  if (const auto &CUI = getCUIndex()) {
463  if (const auto *R = CUI.getFromHash(Hash))
464  return DWOCUs.getUnitForIndexEntry(*R);
465  return nullptr;
466  }
467 
468  // If there's no index, just search through the CUs in the DWO - there's
469  // probably only one unless this is something like LTO - though an in-process
470  // built/cached lookup table could be used in that case to improve repeated
471  // lookups of different CUs in the DWO.
472  for (const auto &DWOCU : dwo_compile_units())
473  if (DWOCU->getDWOId() == Hash)
474  return DWOCU.get();
475  return nullptr;
476 }
477 
479  parseCompileUnits();
480  if (auto *CU = CUs.getUnitForOffset(Offset))
481  return CU->getDIEForOffset(Offset);
482  return DWARFDie();
483 }
484 
486  bool Success = true;
487  DWARFVerifier verifier(OS, *this, DumpOpts);
488 
489  Success &= verifier.handleDebugAbbrev();
490  if (DumpOpts.DumpType & DIDT_DebugInfo)
491  Success &= verifier.handleDebugInfo();
492  if (DumpOpts.DumpType & DIDT_DebugLine)
493  Success &= verifier.handleDebugLine();
494  Success &= verifier.handleAccelTables();
495  return Success;
496 }
497 
499  if (CUIndex)
500  return *CUIndex;
501 
502  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
503 
504  CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
505  CUIndex->parse(CUIndexData);
506  return *CUIndex;
507 }
508 
510  if (TUIndex)
511  return *TUIndex;
512 
513  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
514 
515  TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
516  TUIndex->parse(TUIndexData);
517  return *TUIndex;
518 }
519 
521  if (GdbIndex)
522  return *GdbIndex;
523 
524  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
525  GdbIndex = llvm::make_unique<DWARFGdbIndex>();
526  GdbIndex->parse(GdbIndexData);
527  return *GdbIndex;
528 }
529 
531  if (Abbrev)
532  return Abbrev.get();
533 
534  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
535 
536  Abbrev.reset(new DWARFDebugAbbrev());
537  Abbrev->extract(abbrData);
538  return Abbrev.get();
539 }
540 
542  if (AbbrevDWO)
543  return AbbrevDWO.get();
544 
545  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
546  AbbrevDWO.reset(new DWARFDebugAbbrev());
547  AbbrevDWO->extract(abbrData);
548  return AbbrevDWO.get();
549 }
550 
552  if (Loc)
553  return Loc.get();
554 
555  Loc.reset(new DWARFDebugLoc);
556  // assume all compile units have the same address byte size
557  if (getNumCompileUnits()) {
558  DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
560  Loc->parse(LocData);
561  }
562  return Loc.get();
563 }
564 
566  if (LocDWO)
567  return LocDWO.get();
568 
569  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0);
570  LocDWO.reset(new DWARFDebugLocDWO());
571  LocDWO->parse(LocData);
572  return LocDWO.get();
573 }
574 
576  if (Aranges)
577  return Aranges.get();
578 
579  Aranges.reset(new DWARFDebugAranges());
580  Aranges->generate(this);
581  return Aranges.get();
582 }
583 
585  if (DebugFrame)
586  return DebugFrame.get();
587 
588  // There's a "bug" in the DWARFv3 standard with respect to the target address
589  // size within debug frame sections. While DWARF is supposed to be independent
590  // of its container, FDEs have fields with size being "target address size",
591  // which isn't specified in DWARF in general. It's only specified for CUs, but
592  // .eh_frame can appear without a .debug_info section. Follow the example of
593  // other tools (libdwarf) and extract this from the container (ObjectFile
594  // provides this information). This problem is fixed in DWARFv4
595  // See this dwarf-discuss discussion for more details:
596  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
597  DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
598  DObj->getAddressSize());
599  DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
600  DebugFrame->parse(debugFrameData);
601  return DebugFrame.get();
602 }
603 
605  if (EHFrame)
606  return EHFrame.get();
607 
608  DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
609  DObj->getAddressSize());
610  DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
611  DebugFrame->parse(debugFrameData);
612  return DebugFrame.get();
613 }
614 
616  if (Macro)
617  return Macro.get();
618 
619  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
620  Macro.reset(new DWARFDebugMacro());
621  Macro->parse(MacinfoData);
622  return Macro.get();
623 }
624 
625 static DWARFAcceleratorTable &
626 getAccelTable(std::unique_ptr<DWARFAcceleratorTable> &Cache,
627  const DWARFObject &Obj, const DWARFSection &Section,
628  StringRef StringSection, bool IsLittleEndian) {
629  if (Cache)
630  return *Cache;
631  DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
632  DataExtractor StrData(StringSection, IsLittleEndian, 0);
633  Cache.reset(new DWARFAcceleratorTable(AccelSection, StrData));
634  Cache->extract();
635  return *Cache;
636 }
637 
639  return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
640  DObj->getStringSection(), isLittleEndian());
641 }
642 
644  return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
645  DObj->getStringSection(), isLittleEndian());
646 }
647 
649  return getAccelTable(AppleNamespaces, *DObj,
650  DObj->getAppleNamespacesSection(),
651  DObj->getStringSection(), isLittleEndian());
652 }
653 
655  return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
656  DObj->getStringSection(), isLittleEndian());
657 }
658 
659 const DWARFLineTable *
661  if (!Line)
662  Line.reset(new DWARFDebugLine);
663 
664  auto UnitDIE = U->getUnitDIE();
665  if (!UnitDIE)
666  return nullptr;
667 
668  auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
669  if (!Offset)
670  return nullptr; // No line table for this compile unit.
671 
672  uint32_t stmtOffset = *Offset + U->getLineTableOffset();
673  // See if the line table is cached.
674  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
675  return lt;
676 
677  // Make sure the offset is good before we try to parse.
678  if (stmtOffset >= U->getLineSection().Data.size())
679  return nullptr;
680 
681  // We have to parse it first.
683  U->getAddressByteSize());
684  return Line->getOrParseLineTable(lineData, stmtOffset, U);
685 }
686 
687 void DWARFContext::parseCompileUnits() {
688  CUs.parse(*this, DObj->getInfoSection());
689 }
690 
691 void DWARFContext::parseTypeUnits() {
692  if (!TUs.empty())
693  return;
694  DObj->forEachTypesSections([&](const DWARFSection &S) {
695  TUs.emplace_back();
696  TUs.back().parse(*this, S);
697  });
698 }
699 
700 void DWARFContext::parseDWOCompileUnits() {
701  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
702 }
703 
704 void DWARFContext::parseDWOTypeUnits() {
705  if (!DWOTUs.empty())
706  return;
707  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
708  DWOTUs.emplace_back();
709  DWOTUs.back().parseDWO(*this, S);
710  });
711 }
712 
713 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
714  parseCompileUnits();
715  return CUs.getUnitForOffset(Offset);
716 }
717 
718 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
719  // First, get the offset of the compile unit.
720  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
721  // Retrieve the compile unit.
722  return getCompileUnitForOffset(CUOffset);
723 }
724 
726  DIEsForAddress Result;
727 
728  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
729  if (!CU)
730  return Result;
731 
732  Result.CompileUnit = CU;
733  Result.FunctionDIE = CU->getSubroutineForAddress(Address);
734 
735  std::vector<DWARFDie> Worklist;
736  Worklist.push_back(Result.FunctionDIE);
737  while (!Worklist.empty()) {
738  DWARFDie DIE = Worklist.back();
739  Worklist.pop_back();
740 
741  if (DIE.getTag() == DW_TAG_lexical_block &&
742  DIE.addressRangeContainsAddress(Address)) {
743  Result.BlockDIE = DIE;
744  break;
745  }
746 
747  for (auto Child : DIE)
748  Worklist.push_back(Child);
749  }
750 
751  return Result;
752 }
753 
755  uint64_t Address,
756  FunctionNameKind Kind,
757  std::string &FunctionName,
758  uint32_t &StartLine) {
759  // The address may correspond to instruction in some inlined function,
760  // so we have to build the chain of inlined functions and take the
761  // name of the topmost function in it.
762  SmallVector<DWARFDie, 4> InlinedChain;
763  CU->getInlinedChainForAddress(Address, InlinedChain);
764  if (InlinedChain.empty())
765  return false;
766 
767  const DWARFDie &DIE = InlinedChain[0];
768  bool FoundResult = false;
769  const char *Name = nullptr;
770  if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
771  FunctionName = Name;
772  FoundResult = true;
773  }
774  if (auto DeclLineResult = DIE.getDeclLine()) {
775  StartLine = DeclLineResult;
776  FoundResult = true;
777  }
778 
779  return FoundResult;
780 }
781 
783  DILineInfoSpecifier Spec) {
784  DILineInfo Result;
785 
786  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
787  if (!CU)
788  return Result;
790  Result.FunctionName,
791  Result.StartLine);
792  if (Spec.FLIKind != FileLineInfoKind::None) {
793  if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
794  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
795  Spec.FLIKind, Result);
796  }
797  return Result;
798 }
799 
802  DILineInfoSpecifier Spec) {
803  DILineInfoTable Lines;
804  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
805  if (!CU)
806  return Lines;
807 
808  std::string FunctionName = "<invalid>";
809  uint32_t StartLine = 0;
810  getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
811  StartLine);
812 
813  // If the Specifier says we don't need FileLineInfo, just
814  // return the top-most function at the starting address.
815  if (Spec.FLIKind == FileLineInfoKind::None) {
816  DILineInfo Result;
817  Result.FunctionName = FunctionName;
818  Result.StartLine = StartLine;
819  Lines.push_back(std::make_pair(Address, Result));
820  return Lines;
821  }
822 
823  const DWARFLineTable *LineTable = getLineTableForUnit(CU);
824 
825  // Get the index of row we're looking for in the line table.
826  std::vector<uint32_t> RowVector;
827  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
828  return Lines;
829 
830  for (uint32_t RowIndex : RowVector) {
831  // Take file number and line/column from the row.
832  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
833  DILineInfo Result;
834  LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
835  Spec.FLIKind, Result.FileName);
836  Result.FunctionName = FunctionName;
837  Result.Line = Row.Line;
838  Result.Column = Row.Column;
839  Result.StartLine = StartLine;
840  Lines.push_back(std::make_pair(Row.Address, Result));
841  }
842 
843  return Lines;
844 }
845 
848  DILineInfoSpecifier Spec) {
849  DIInliningInfo InliningInfo;
850 
851  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
852  if (!CU)
853  return InliningInfo;
854 
855  const DWARFLineTable *LineTable = nullptr;
856  SmallVector<DWARFDie, 4> InlinedChain;
857  CU->getInlinedChainForAddress(Address, InlinedChain);
858  if (InlinedChain.size() == 0) {
859  // If there is no DIE for address (e.g. it is in unavailable .dwo file),
860  // try to at least get file/line info from symbol table.
861  if (Spec.FLIKind != FileLineInfoKind::None) {
862  DILineInfo Frame;
863  LineTable = getLineTableForUnit(CU);
864  if (LineTable &&
865  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
866  Spec.FLIKind, Frame))
867  InliningInfo.addFrame(Frame);
868  }
869  return InliningInfo;
870  }
871 
872  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
873  for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
874  DWARFDie &FunctionDIE = InlinedChain[i];
875  DILineInfo Frame;
876  // Get function name if necessary.
877  if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
878  Frame.FunctionName = Name;
879  if (auto DeclLineResult = FunctionDIE.getDeclLine())
880  Frame.StartLine = DeclLineResult;
881  if (Spec.FLIKind != FileLineInfoKind::None) {
882  if (i == 0) {
883  // For the topmost frame, initialize the line table of this
884  // compile unit and fetch file/line info from it.
885  LineTable = getLineTableForUnit(CU);
886  // For the topmost routine, get file/line info from line table.
887  if (LineTable)
888  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
889  Spec.FLIKind, Frame);
890  } else {
891  // Otherwise, use call file, call line and call column from
892  // previous DIE in inlined chain.
893  if (LineTable)
894  LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
895  Spec.FLIKind, Frame.FileName);
896  Frame.Line = CallLine;
897  Frame.Column = CallColumn;
898  Frame.Discriminator = CallDiscriminator;
899  }
900  // Get call file/line/column of a current DIE.
901  if (i + 1 < n) {
902  FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
903  CallDiscriminator);
904  }
905  }
906  InliningInfo.addFrame(Frame);
907  }
908  return InliningInfo;
909 }
910 
911 std::shared_ptr<DWARFContext>
913  if (auto S = DWP.lock()) {
914  DWARFContext *Ctxt = S->Context.get();
915  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
916  }
917 
918  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
919 
920  if (auto S = Entry->lock()) {
921  DWARFContext *Ctxt = S->Context.get();
922  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
923  }
924 
926  if (!CheckedForDWP) {
927  SmallString<128> DWPName;
929  this->DWPName.empty()
930  ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
931  : StringRef(this->DWPName));
932  if (Obj) {
933  Entry = &DWP;
934  return Obj;
935  } else {
936  CheckedForDWP = true;
937  // TODO: Should this error be handled (maybe in a high verbosity mode)
938  // before falling back to .dwo files?
939  consumeError(Obj.takeError());
940  }
941  }
942 
943  return object::ObjectFile::createObjectFile(AbsolutePath);
944  }();
945 
946  if (!Obj) {
947  // TODO: Actually report errors helpfully.
948  consumeError(Obj.takeError());
949  return nullptr;
950  }
951 
952  auto S = std::make_shared<DWOFile>();
953  S->File = std::move(Obj.get());
954  S->Context = DWARFContext::create(*S->File.getBinary());
955  *Entry = S;
956  auto *Ctxt = S->Context.get();
957  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
958 }
959 
960 static Error createError(const Twine &Reason, llvm::Error E) {
961  return make_error<StringError>(Reason + toString(std::move(E)),
963 }
964 
965 /// SymInfo contains information about symbol: it's address
966 /// and section index which is -1LL for absolute symbols.
967 struct SymInfo {
968  uint64_t Address;
969  uint64_t SectionIndex;
970 };
971 
972 /// Returns the address of symbol relocation used against and a section index.
973 /// Used for futher relocations computation. Symbol's section load address is
975  const RelocationRef &Reloc,
976  const LoadedObjectInfo *L,
977  std::map<SymbolRef, SymInfo> &Cache) {
978  SymInfo Ret = {0, (uint64_t)-1LL};
980  object::symbol_iterator Sym = Reloc.getSymbol();
981 
982  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
983  // First calculate the address of the symbol or section as it appears
984  // in the object file
985  if (Sym != Obj.symbol_end()) {
986  bool New;
987  std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
988  if (!New)
989  return CacheIt->second;
990 
991  Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
992  if (!SymAddrOrErr)
993  return createError("failed to compute symbol address: ",
994  SymAddrOrErr.takeError());
995 
996  // Also remember what section this symbol is in for later
997  auto SectOrErr = Sym->getSection();
998  if (!SectOrErr)
999  return createError("failed to get symbol section: ",
1000  SectOrErr.takeError());
1001 
1002  RSec = *SectOrErr;
1003  Ret.Address = *SymAddrOrErr;
1004  } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1005  RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1006  Ret.Address = RSec->getAddress();
1007  }
1008 
1009  if (RSec != Obj.section_end())
1010  Ret.SectionIndex = RSec->getIndex();
1011 
1012  // If we are given load addresses for the sections, we need to adjust:
1013  // SymAddr = (Address of Symbol Or Section in File) -
1014  // (Address of Section in File) +
1015  // (Load Address of Section)
1016  // RSec is now either the section being targeted or the section
1017  // containing the symbol being targeted. In either case,
1018  // we need to perform the same computation.
1019  if (L && RSec != Obj.section_end())
1020  if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1021  Ret.Address += SectionLoadAddress - RSec->getAddress();
1022 
1023  if (CacheIt != Cache.end())
1024  CacheIt->second = Ret;
1025 
1026  return Ret;
1027 }
1028 
1029 static bool isRelocScattered(const object::ObjectFile &Obj,
1030  const RelocationRef &Reloc) {
1031  const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1032  if (!MachObj)
1033  return false;
1034  // MachO also has relocations that point to sections and
1035  // scattered relocations.
1036  auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1037  return MachObj->isRelocationScattered(RelocInfo);
1038 }
1039 
1041  errs() << "error: " + toString(std::move(E)) << '\n';
1042  return ErrorPolicy::Continue;
1043 }
1044 
1045 namespace {
1046 struct DWARFSectionMap final : public DWARFSection {
1047  RelocAddrMap Relocs;
1048 };
1049 
1050 class DWARFObjInMemory final : public DWARFObject {
1051  bool IsLittleEndian;
1052  uint8_t AddressSize;
1053  StringRef FileName;
1054  const object::ObjectFile *Obj = nullptr;
1055  std::vector<SectionName> SectionNames;
1056 
1057  using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1058  std::map<object::SectionRef, unsigned>>;
1059 
1060  TypeSectionMap TypesSections;
1061  TypeSectionMap TypesDWOSections;
1062 
1063  DWARFSectionMap InfoSection;
1064  DWARFSectionMap LocSection;
1065  DWARFSectionMap LineSection;
1066  DWARFSectionMap RangeSection;
1067  DWARFSectionMap StringOffsetSection;
1068  DWARFSectionMap InfoDWOSection;
1069  DWARFSectionMap LineDWOSection;
1070  DWARFSectionMap LocDWOSection;
1071  DWARFSectionMap StringOffsetDWOSection;
1072  DWARFSectionMap RangeDWOSection;
1073  DWARFSectionMap AddrSection;
1074  DWARFSectionMap AppleNamesSection;
1075  DWARFSectionMap AppleTypesSection;
1076  DWARFSectionMap AppleNamespacesSection;
1077  DWARFSectionMap AppleObjCSection;
1078 
1079  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1081  .Case("debug_info", &InfoSection)
1082  .Case("debug_loc", &LocSection)
1083  .Case("debug_line", &LineSection)
1084  .Case("debug_str_offsets", &StringOffsetSection)
1085  .Case("debug_ranges", &RangeSection)
1086  .Case("debug_info.dwo", &InfoDWOSection)
1087  .Case("debug_loc.dwo", &LocDWOSection)
1088  .Case("debug_line.dwo", &LineDWOSection)
1089  .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1090  .Case("debug_addr", &AddrSection)
1091  .Case("apple_names", &AppleNamesSection)
1092  .Case("apple_types", &AppleTypesSection)
1093  .Case("apple_namespaces", &AppleNamespacesSection)
1094  .Case("apple_namespac", &AppleNamespacesSection)
1095  .Case("apple_objc", &AppleObjCSection)
1096  .Default(nullptr);
1097  }
1098 
1099  StringRef AbbrevSection;
1100  StringRef ARangeSection;
1101  StringRef DebugFrameSection;
1102  StringRef EHFrameSection;
1103  StringRef StringSection;
1104  StringRef MacinfoSection;
1105  StringRef PubNamesSection;
1106  StringRef PubTypesSection;
1107  StringRef GnuPubNamesSection;
1108  StringRef AbbrevDWOSection;
1109  StringRef StringDWOSection;
1110  StringRef GnuPubTypesSection;
1111  StringRef CUIndexSection;
1112  StringRef GdbIndexSection;
1113  StringRef TUIndexSection;
1114 
1115  SmallVector<SmallString<32>, 4> UncompressedSections;
1116 
1117  StringRef *mapSectionToMember(StringRef Name) {
1118  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1119  return &Sec->Data;
1121  .Case("debug_abbrev", &AbbrevSection)
1122  .Case("debug_aranges", &ARangeSection)
1123  .Case("debug_frame", &DebugFrameSection)
1124  .Case("eh_frame", &EHFrameSection)
1125  .Case("debug_str", &StringSection)
1126  .Case("debug_macinfo", &MacinfoSection)
1127  .Case("debug_pubnames", &PubNamesSection)
1128  .Case("debug_pubtypes", &PubTypesSection)
1129  .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1130  .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1131  .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1132  .Case("debug_str.dwo", &StringDWOSection)
1133  .Case("debug_cu_index", &CUIndexSection)
1134  .Case("debug_tu_index", &TUIndexSection)
1135  .Case("gdb_index", &GdbIndexSection)
1136  // Any more debug info sections go here.
1137  .Default(nullptr);
1138  }
1139 
1140  /// If Sec is compressed section, decompresses and updates its contents
1141  /// provided by Data. Otherwise leaves it unchanged.
1142  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1143  StringRef &Data) {
1144  if (!Decompressor::isCompressed(Sec))
1145  return Error::success();
1146 
1147  Expected<Decompressor> Decompressor =
1148  Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1149  if (!Decompressor)
1150  return Decompressor.takeError();
1151 
1152  SmallString<32> Out;
1153  if (auto Err = Decompressor->resizeAndDecompress(Out))
1154  return Err;
1155 
1156  UncompressedSections.emplace_back(std::move(Out));
1157  Data = UncompressedSections.back();
1158 
1159  return Error::success();
1160  }
1161 
1162 public:
1163  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1164  uint8_t AddrSize, bool IsLittleEndian)
1165  : IsLittleEndian(IsLittleEndian) {
1166  for (const auto &SecIt : Sections) {
1167  if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1168  *SectionData = SecIt.second->getBuffer();
1169  }
1170  }
1171  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1172  function_ref<ErrorPolicy(Error)> HandleError)
1173  : IsLittleEndian(Obj.isLittleEndian()),
1174  AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1175  Obj(&Obj) {
1176 
1177  StringMap<unsigned> SectionAmountMap;
1178  for (const SectionRef &Section : Obj.sections()) {
1179  StringRef Name;
1180  Section.getName(Name);
1181  ++SectionAmountMap[Name];
1182  SectionNames.push_back({ Name, true });
1183 
1184  // Skip BSS and Virtual sections, they aren't interesting.
1185  if (Section.isBSS() || Section.isVirtual())
1186  continue;
1187 
1188  // Skip sections stripped by dsymutil.
1189  if (Section.isStripped())
1190  continue;
1191 
1192  StringRef Data;
1193  section_iterator RelocatedSection = Section.getRelocatedSection();
1194  // Try to obtain an already relocated version of this section.
1195  // Else use the unrelocated section from the object file. We'll have to
1196  // apply relocations ourselves later.
1197  if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
1198  Section.getContents(Data);
1199 
1200  if (auto Err = maybeDecompress(Section, Name, Data)) {
1201  ErrorPolicy EP = HandleError(createError(
1202  "failed to decompress '" + Name + "', ", std::move(Err)));
1203  if (EP == ErrorPolicy::Halt)
1204  return;
1205  continue;
1206  }
1207 
1208  // Compressed sections names in GNU style starts from ".z",
1209  // at this point section is decompressed and we drop compression prefix.
1210  Name = Name.substr(
1211  Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1212 
1213  // Map platform specific debug section names to DWARF standard section
1214  // names.
1215  Name = Obj.mapDebugSectionName(Name);
1216 
1217  if (StringRef *SectionData = mapSectionToMember(Name)) {
1218  *SectionData = Data;
1219  if (Name == "debug_ranges") {
1220  // FIXME: Use the other dwo range section when we emit it.
1221  RangeDWOSection.Data = Data;
1222  }
1223  } else if (Name == "debug_types") {
1224  // Find debug_types data by section rather than name as there are
1225  // multiple, comdat grouped, debug_types sections.
1226  TypesSections[Section].Data = Data;
1227  } else if (Name == "debug_types.dwo") {
1228  TypesDWOSections[Section].Data = Data;
1229  }
1230 
1231  if (RelocatedSection == Obj.section_end())
1232  continue;
1233 
1234  StringRef RelSecName;
1235  StringRef RelSecData;
1236  RelocatedSection->getName(RelSecName);
1237 
1238  // If the section we're relocating was relocated already by the JIT,
1239  // then we used the relocated version above, so we do not need to process
1240  // relocations for it now.
1241  if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1242  continue;
1243 
1244  // In Mach-o files, the relocations do not need to be applied if
1245  // there is no load offset to apply. The value read at the
1246  // relocation point already factors in the section address
1247  // (actually applying the relocations will produce wrong results
1248  // as the section address will be added twice).
1249  if (!L && isa<MachOObjectFile>(&Obj))
1250  continue;
1251 
1252  RelSecName = RelSecName.substr(
1253  RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1254 
1255  // TODO: Add support for relocations in other sections as needed.
1256  // Record relocations for the debug_info and debug_line sections.
1257  DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1258  RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1259  if (!Map) {
1260  // Find debug_types relocs by section rather than name as there are
1261  // multiple, comdat grouped, debug_types sections.
1262  if (RelSecName == "debug_types")
1263  Map =
1264  &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1265  .Relocs;
1266  else if (RelSecName == "debug_types.dwo")
1267  Map = &static_cast<DWARFSectionMap &>(
1268  TypesDWOSections[*RelocatedSection])
1269  .Relocs;
1270  else
1271  continue;
1272  }
1273 
1274  if (Section.relocation_begin() == Section.relocation_end())
1275  continue;
1276 
1277  // Symbol to [address, section index] cache mapping.
1278  std::map<SymbolRef, SymInfo> AddrCache;
1279  for (const RelocationRef &Reloc : Section.relocations()) {
1280  // FIXME: it's not clear how to correctly handle scattered
1281  // relocations.
1282  if (isRelocScattered(Obj, Reloc))
1283  continue;
1284 
1285  Expected<SymInfo> SymInfoOrErr =
1286  getSymbolInfo(Obj, Reloc, L, AddrCache);
1287  if (!SymInfoOrErr) {
1288  if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1289  return;
1290  continue;
1291  }
1292 
1293  object::RelocVisitor V(Obj);
1294  uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1295  if (V.error()) {
1297  Reloc.getTypeName(Type);
1298  ErrorPolicy EP = HandleError(
1299  createError("failed to compute relocation: " + Type + ", ",
1300  errorCodeToError(object_error::parse_failed)));
1301  if (EP == ErrorPolicy::Halt)
1302  return;
1303  continue;
1304  }
1305  RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1306  Map->insert({Reloc.getOffset(), Rel});
1307  }
1308  }
1309 
1310  for (SectionName &S : SectionNames)
1311  if (SectionAmountMap[S.Name] > 1)
1312  S.IsNameUnique = false;
1313  }
1314 
1316  uint64_t Pos) const override {
1317  auto &Sec = static_cast<const DWARFSectionMap &>(S);
1318  RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1319  if (AI == Sec.Relocs.end())
1320  return None;
1321  return AI->second;
1322  }
1323 
1324  const object::ObjectFile *getFile() const override { return Obj; }
1325 
1326  ArrayRef<SectionName> getSectionNames() const override {
1327  return SectionNames;
1328  }
1329 
1330  bool isLittleEndian() const override { return IsLittleEndian; }
1331  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1332  const DWARFSection &getLineDWOSection() const override {
1333  return LineDWOSection;
1334  }
1335  const DWARFSection &getLocDWOSection() const override {
1336  return LocDWOSection;
1337  }
1338  StringRef getStringDWOSection() const override { return StringDWOSection; }
1339  const DWARFSection &getStringOffsetDWOSection() const override {
1340  return StringOffsetDWOSection;
1341  }
1342  const DWARFSection &getRangeDWOSection() const override {
1343  return RangeDWOSection;
1344  }
1345  const DWARFSection &getAddrSection() const override { return AddrSection; }
1346  StringRef getCUIndexSection() const override { return CUIndexSection; }
1347  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1348  StringRef getTUIndexSection() const override { return TUIndexSection; }
1349 
1350  // DWARF v5
1351  const DWARFSection &getStringOffsetSection() const override {
1352  return StringOffsetSection;
1353  }
1354 
1355  // Sections for DWARF5 split dwarf proposal.
1356  const DWARFSection &getInfoDWOSection() const override {
1357  return InfoDWOSection;
1358  }
1359  void forEachTypesDWOSections(
1360  function_ref<void(const DWARFSection &)> F) const override {
1361  for (auto &P : TypesDWOSections)
1362  F(P.second);
1363  }
1364 
1365  StringRef getAbbrevSection() const override { return AbbrevSection; }
1366  const DWARFSection &getLocSection() const override { return LocSection; }
1367  StringRef getARangeSection() const override { return ARangeSection; }
1368  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1369  StringRef getEHFrameSection() const override { return EHFrameSection; }
1370  const DWARFSection &getLineSection() const override { return LineSection; }
1371  StringRef getStringSection() const override { return StringSection; }
1372  const DWARFSection &getRangeSection() const override { return RangeSection; }
1373  StringRef getMacinfoSection() const override { return MacinfoSection; }
1374  StringRef getPubNamesSection() const override { return PubNamesSection; }
1375  StringRef getPubTypesSection() const override { return PubTypesSection; }
1376  StringRef getGnuPubNamesSection() const override {
1377  return GnuPubNamesSection;
1378  }
1379  StringRef getGnuPubTypesSection() const override {
1380  return GnuPubTypesSection;
1381  }
1382  const DWARFSection &getAppleNamesSection() const override {
1383  return AppleNamesSection;
1384  }
1385  const DWARFSection &getAppleTypesSection() const override {
1386  return AppleTypesSection;
1387  }
1388  const DWARFSection &getAppleNamespacesSection() const override {
1389  return AppleNamespacesSection;
1390  }
1391  const DWARFSection &getAppleObjCSection() const override {
1392  return AppleObjCSection;
1393  }
1394 
1395  StringRef getFileName() const override { return FileName; }
1396  uint8_t getAddressSize() const override { return AddressSize; }
1397  const DWARFSection &getInfoSection() const override { return InfoSection; }
1398  void forEachTypesSections(
1399  function_ref<void(const DWARFSection &)> F) const override {
1400  for (auto &P : TypesSections)
1401  F(P.second);
1402  }
1403 };
1404 } // namespace
1405 
1406 std::unique_ptr<DWARFContext>
1408  function_ref<ErrorPolicy(Error)> HandleError,
1409  std::string DWPName) {
1410  auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1411  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1412 }
1413 
1414 std::unique_ptr<DWARFContext>
1415 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1416  uint8_t AddrSize, bool isLittleEndian) {
1417  auto DObj =
1418  llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
1419  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
1420 }
1421 
1423  // Detect the architecture from the object file. We usually don't need OS
1424  // info to lookup a target and create register info.
1425  Triple TT;
1426  TT.setArch(Triple::ArchType(Obj.getArch()));
1429  std::string TargetLookupError;
1430  const Target *TheTarget =
1431  TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
1432  if (!TargetLookupError.empty())
1433  return make_error<StringError>(TargetLookupError, inconvertibleErrorCode());
1434  RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
1435  return Error::success();
1436 }
const DWARFUnitIndex & getTUIndex()
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
uint32_t StartLine
Definition: DIContext.h:36
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
Definition: ObjectFile.cpp:152
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:389
const DWARFDebugFrame * getEHFrame()
Get a pointer to the parsed eh frame information object.
void push_back(const T &Elt)
Definition: SmallVector.h:212
uint32_t Discriminator
Definition: DIContext.h:39
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.
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
Definition: raw_ostream.h:217
static void dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, bool LittleEndian)
std::string FileName
Definition: DIContext.h:32
A parsed .debug_frame or .eh_frame section.
static DWARFAcceleratorTable & getAccelTable(std::unique_ptr< DWARFAcceleratorTable > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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.
virtual bool getLoadedSectionContents(const object::SectionRef &Sec, StringRef &Data) const
If conveniently available, return the content of the given Section.
Definition: DIContext.h:241
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
ErrorPolicy
Used as a return value for a error callback passed to DWARF context.
Definition: DWARFContext.h:54
bool addressRangeContainsAddress(const uint64_t Address) const
Definition: DWARFDie.cpp:388
void setVendor(VendorType Kind)
setVendor - Set the vendor (second) component of the triple to a known type.
Definition: Triple.cpp:1123
StringRef getFileName() const
Definition: Binary.cpp:41
void dump(raw_ostream &OS) const
DWARFDie getDIEForOffset(uint32_t Offset)
Get a DIE given an exact offset.
uint64_t Address
DWARFGdbIndex & getGdbIndex()
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
uint32_t findAddress(uint64_t Address) const
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
bool handleDebugLine()
Verify the information in the .debug_line section.
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:89
uint32_t Line
An unsigned integer indicating a source line number.
DIEsForAddress getDIEsForAddress(uint64_t Address)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
This class is the base class for all object file types.
Definition: ObjectFile.h:189
This class implements a map that also provides access to all stored values in a deterministic order...
Definition: MapVector.h:38
unsigned getNumTypeUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:176
F(f)
void setOS(OSType Kind)
setOS - Set the operating system (third) component of the triple to a known type. ...
Definition: Triple.cpp:1127
void addFrame(const DILineInfo &Frame)
Definition: DIContext.h:97
unsigned getMaxVersion() const
Definition: DWARFContext.h:210
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:113
Error takeError()
Take ownership of the stored error.
Definition: Error.h:537
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
uint16_t getU16(uint32_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
virtual unsigned getArch() const =0
std::unique_ptr< const DWARFObject > DObj
Definition: DWARFContext.h:113
bool handleDebugInfo()
Verify the information in the .debug_info section.
raw_ostream & write_uuid(const uuid_t UUID)
A format-neutral container for source line information.
Definition: DIContext.h:31
DWARFDie getSubroutineForAddress(uint64_t Address)
Returns subprogram DIE with address range encompassing the provided address.
Definition: DWARFUnit.cpp:374
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:191
void dump(raw_ostream &OS, Optional< uint64_t > Offset) const
Dump the section data into the given stream.
Definition: BitVector.h:920
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:947
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, std::string &FunctionName, uint32_t &StartLine)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:518
const char * getCompilationDir()
Definition: DWARFUnit.cpp:167
FunctionNameKind FNKind
Definition: DIContext.h:122
unsigned getNumCompileUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:170
const DWARFSection & getLineSection() const
Definition: DWARFUnit.h:234
FileLineInfoKind FLIKind
Definition: DIContext.h:121
uint64_t Address
The program-counter value corresponding to a machine instruction generated by the compiler...
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) 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:421
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const
Obtain the Load Address of a section by SectionRef.
Definition: DIContext.h:226
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:286
unsigned getNumDWOTypeUnits()
Get the number of compile units in the DWO context.
Definition: DWARFContext.h:188
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:278
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:127
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
section_iterator_range sections() const
Definition: ObjectFile.h:273
DWARFCompileUnit * getCompileUnitAtIndex(unsigned index)
Get the compile unit at the specified index for this compile unit.
Definition: DWARFContext.h:194
const DWARFAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
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:598
const std::string & str() const
Definition: Triple.h:354
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:417
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:363
uint64_t SectionIndex
Error loadRegisterInfo(const object::ObjectFile &Obj)
Loads register info for the architecture of the provided object file.
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:153
virtual StringRef mapDebugSectionName(StringRef Name) const
Maps a debug section name to a standard DWARF section name.
Definition: ObjectFile.h:301
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const
Test the availability of length bytes of data from offset.
#define P(N)
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:43
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
uint32_t Column
Definition: DIContext.h:35
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
Controls which fields of DILineInfo container should be filled with data.
Definition: DIContext.h:117
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition: DIContext.h:170
uint16_t File
An unsigned integer indicating the identity of the source file corresponding to a machine instruction...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:78
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro object.
A format-neutral container for inlined code description.
Definition: DIContext.h:77
A structured debug information entry.
Definition: DIE.h:662
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:265
void dump(raw_ostream &OS) const
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev, debug_abbrev.dwo.
static Error createError(const Twine &Reason, llvm::Error E)
DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
static ErrorPolicy defaultErrorHandler(Error E)
Function used to handle default error reporting policy.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
void dump(raw_ostream &OS)
virtual basic_symbol_iterator symbol_end() const =0
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)
Dump the UUID load command.
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
void dump(raw_ostream &OS) const
Print the macro list found within the debug_macinfo section.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Definition: StringExtras.h:43
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:347
uint64_t getU64(uint32_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:962
bool isLittleEndian() const
Definition: Binary.h:131
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off, uint64_t *SectionIndex=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset...
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Standard .debug_line state machine structure.
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr, function_ref< ErrorPolicy(Error)> HandleError=defaultErrorHandler, std::string DWPName="")
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
bool lookupAddressRange(uint64_t Address, uint64_t Size, std::vector< uint32_t > &Result) const
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
uint16_t Column
An unsigned integer indicating a column number within a source line.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:329
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:788
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
uint32_t Line
Definition: DIContext.h:34
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
static Expected< SymInfo > getSymbolInfo(const object::ObjectFile &Obj, const RelocationRef &Reloc, const LoadedObjectInfo *L, std::map< SymbolRef, SymInfo > &Cache)
Returns the address of symbol relocation used against and a section index.
std::string FunctionName
Definition: DIContext.h:33
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:59
tu_section_iterator_range dwo_type_unit_sections()
Get type units in the DWO context.
Definition: DWARFContext.h:164
A range adaptor for a pair of iterators.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:224
This file contains constants used for implementing Dwarf debug support.
Target - Wrapper for Target specific information.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition: DIContext.h:211
const DWARFAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
loop extract
void dump(raw_ostream &OS) const
#define Success
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
RelocAddrEntry contains relocated value and section index.
Definition: DWARFRelocMap.h:20
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, bool LittleEndian, unsigned MaxVersion)
A class that verifies DWARF debug information given a DWARF Context.
Definition: DWARFVerifier.h:34
void dump(raw_ostream &OS) const
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:656
virtual section_iterator section_end() const =0
dwarf::Tag getTag() const
Definition: DWARFDie.h:72
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
Wraps the returned DIEs for a given address.
Definition: DWARFContext.h:261
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
const char * getCStr(uint32_t *offset_ptr) const
Extract a C string from *offset_ptr.
cu_iterator_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:146
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
const DWARFAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::array< Optional< uint64_t >, DIDT_ID_Count > DumpOffsets)
Dump a textual representation to OS.
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="")
bool isLittleEndian() const
Definition: DWARFContext.h:279
const DWARFUnitIndex & getCUIndex()
SymInfo contains information about symbol: it&#39;s address and section index which is -1LL for absolute ...
DINameKind FunctionNameKind
Definition: DIContext.h:119
cu_iterator_range dwo_compile_units()
Get compile units in the DWO context.
Definition: DWARFContext.h:158
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *cu)
Get a pointer to a parsed line table corresponding to a compile unit.
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
tu_section_iterator_range type_unit_sections()
Get type units in this context.
Definition: DWARFContext.h:152
const DWARFAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
const uint64_t Version
Definition: InstrProf.h:867
bool extract(const DWARFDataExtractor &data, uint32_t *offset_ptr)
uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value=0)
Definition: RelocVisitor.h:42
uint32_t getLineTableOffset() const
Definition: DWARFUnit.h:399
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:396
void setArch(ArchType Kind)
setArch - Set the architecture (first) component of the triple to a known type.
Definition: Triple.cpp:1119
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
Base class for object file relocation visitors.
Definition: RelocVisitor.h:35
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
Definition: Path.cpp:590
void dump(raw_ostream &OS) const
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:73