LLVM  8.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"
36 #include "llvm/MC/MCRegisterInfo.h"
38 #include "llvm/Object/MachO.h"
39 #include "llvm/Object/ObjectFile.h"
41 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/Error.h"
44 #include "llvm/Support/Format.h"
46 #include "llvm/Support/Path.h"
48 #include "llvm/Support/WithColor.h"
50 #include <algorithm>
51 #include <cstdint>
52 #include <deque>
53 #include <map>
54 #include <string>
55 #include <utility>
56 #include <vector>
57 
58 using namespace llvm;
59 using namespace dwarf;
60 using namespace object;
61 
62 #define DEBUG_TYPE "dwarf"
63 
67 
68 DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
69  std::string DWPName)
70  : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {}
71 
72 DWARFContext::~DWARFContext() = default;
73 
74 /// Dump the UUID load command.
75 static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
76  auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
77  if (!MachO)
78  return;
79  for (auto LC : MachO->load_commands()) {
81  if (LC.C.cmd == MachO::LC_UUID) {
82  if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
83  OS << "error: UUID load command is too short.\n";
84  return;
85  }
86  OS << "UUID: ";
87  memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
88  OS.write_uuid(UUID);
89  Triple T = MachO->getArchTriple();
90  OS << " (" << T.getArchName() << ')';
91  OS << ' ' << MachO->getFileName() << '\n';
92  }
93  }
94 }
95 
97  std::vector<Optional<StrOffsetsContributionDescriptor>>;
98 
99 // Collect all the contributions to the string offsets table from all units,
100 // sort them by their starting offsets and remove duplicates.
103  ContributionCollection Contributions;
104  for (const auto &U : Units)
105  Contributions.push_back(U->getStringOffsetsTableContribution());
106  // Sort the contributions so that any invalid ones are placed at
107  // the start of the contributions vector. This way they are reported
108  // first.
109  llvm::sort(Contributions,
112  if (L && R)
113  return L->Base < R->Base;
114  return R.hasValue();
115  });
116 
117  // Uniquify contributions, as it is possible that units (specifically
118  // type units in dwo or dwp files) share contributions. We don't want
119  // to report them more than once.
120  Contributions.erase(
121  std::unique(Contributions.begin(), Contributions.end(),
124  if (L && R)
125  return L->Base == R->Base && L->Size == R->Size;
126  return false;
127  }),
128  Contributions.end());
129  return Contributions;
130 }
131 
133  raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
134  const DWARFSection &StringOffsetsSection, StringRef StringSection,
135  DWARFContext::unit_iterator_range Units, bool LittleEndian) {
136  auto Contributions = collectContributionData(Units);
137  DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
138  DataExtractor StrData(StringSection, LittleEndian, 0);
139  uint64_t SectionSize = StringOffsetsSection.Data.size();
140  uint32_t Offset = 0;
141  for (auto &Contribution : Contributions) {
142  // Report an ill-formed contribution.
143  if (!Contribution) {
144  OS << "error: invalid contribution to string offsets table in section ."
145  << SectionName << ".\n";
146  return;
147  }
148 
149  dwarf::DwarfFormat Format = Contribution->getFormat();
150  uint16_t Version = Contribution->getVersion();
151  uint64_t ContributionHeader = Contribution->Base;
152  // In DWARF v5 there is a contribution header that immediately precedes
153  // the string offsets base (the location we have previously retrieved from
154  // the CU DIE's DW_AT_str_offsets attribute). The header is located either
155  // 8 or 16 bytes before the base, depending on the contribution's format.
156  if (Version >= 5)
157  ContributionHeader -= Format == DWARF32 ? 8 : 16;
158 
159  // Detect overlapping contributions.
160  if (Offset > ContributionHeader) {
161  OS << "error: overlapping contributions to string offsets table in "
162  "section ."
163  << SectionName << ".\n";
164  return;
165  }
166  // Report a gap in the table.
167  if (Offset < ContributionHeader) {
168  OS << format("0x%8.8x: Gap, length = ", Offset);
169  OS << (ContributionHeader - Offset) << "\n";
170  }
171  OS << format("0x%8.8x: ", (uint32_t)ContributionHeader);
172  // In DWARF v5 the contribution size in the descriptor does not equal
173  // the originally encoded length (it does not contain the length of the
174  // version field and the padding, a total of 4 bytes). Add them back in
175  // for reporting.
176  OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
177  << ", Format = " << (Format == DWARF32 ? "DWARF32" : "DWARF64")
178  << ", Version = " << Version << "\n";
179 
180  Offset = Contribution->Base;
181  unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
182  while (Offset - Contribution->Base < Contribution->Size) {
183  OS << format("0x%8.8x: ", Offset);
184  // FIXME: We can only extract strings if the offset fits in 32 bits.
185  uint64_t StringOffset =
186  StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
187  // Extract the string if we can and display it. Otherwise just report
188  // the offset.
189  if (StringOffset <= std::numeric_limits<uint32_t>::max()) {
190  uint32_t StringOffset32 = (uint32_t)StringOffset;
191  OS << format("%8.8x ", StringOffset32);
192  const char *S = StrData.getCStr(&StringOffset32);
193  if (S)
194  OS << format("\"%s\"", S);
195  } else
196  OS << format("%16.16" PRIx64 " ", StringOffset);
197  OS << "\n";
198  }
199  }
200  // Report a gap at the end of the table.
201  if (Offset < SectionSize) {
202  OS << format("0x%8.8x: Gap, length = ", Offset);
203  OS << (SectionSize - Offset) << "\n";
204  }
205 }
206 
207 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
208 // string offsets section, where each compile or type unit contributes a
209 // number of entries (string offsets), with each contribution preceded by
210 // a header containing size and version number. Alternatively, it may be a
211 // monolithic series of string offsets, as generated by the pre-DWARF v5
212 // implementation of split DWARF.
214  const DWARFObject &Obj,
215  const DWARFSection &StringOffsetsSection,
216  StringRef StringSection,
218  bool LittleEndian, unsigned MaxVersion) {
219  // If we have at least one (compile or type) unit with DWARF v5 or greater,
220  // we assume that the section is formatted like a DWARF v5 string offsets
221  // section.
222  if (MaxVersion >= 5)
223  dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
224  StringSection, Units, LittleEndian);
225  else {
226  DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
227  uint32_t offset = 0;
228  uint64_t size = StringOffsetsSection.Data.size();
229  // Ensure that size is a multiple of the size of an entry.
230  if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
231  OS << "error: size of ." << SectionName << " is not a multiple of "
232  << sizeof(uint32_t) << ".\n";
233  size &= -(uint64_t)sizeof(uint32_t);
234  }
235  DataExtractor StrData(StringSection, LittleEndian, 0);
236  while (offset < size) {
237  OS << format("0x%8.8x: ", offset);
238  uint32_t StringOffset = strOffsetExt.getU32(&offset);
239  OS << format("%8.8x ", StringOffset);
240  const char *S = StrData.getCStr(&StringOffset);
241  if (S)
242  OS << format("\"%s\"", S);
243  OS << "\n";
244  }
245  }
246 }
247 
248 // Dump the .debug_addr section.
249 static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
250  DIDumpOptions DumpOpts, uint16_t Version,
251  uint8_t AddrSize) {
252  uint32_t Offset = 0;
253  while (AddrData.isValidOffset(Offset)) {
254  DWARFDebugAddrTable AddrTable;
255  uint32_t TableOffset = Offset;
256  if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
258  WithColor::error() << toString(std::move(Err)) << '\n';
259  // Keep going after an error, if we can, assuming that the length field
260  // could be read. If it couldn't, stop reading the section.
261  if (!AddrTable.hasValidLength())
262  break;
263  uint64_t Length = AddrTable.getLength();
264  Offset = TableOffset + Length;
265  } else {
266  AddrTable.dump(OS, DumpOpts);
267  }
268  }
269 }
270 
271 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
272 static void
275  LookupPooledAddress,
276  DIDumpOptions DumpOpts) {
277  uint32_t Offset = 0;
278  while (rnglistData.isValidOffset(Offset)) {
280  uint32_t TableOffset = Offset;
281  if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
282  WithColor::error() << toString(std::move(Err)) << '\n';
283  uint64_t Length = Rnglists.length();
284  // Keep going after an error, if we can, assuming that the length field
285  // could be read. If it couldn't, stop reading the section.
286  if (Length == 0)
287  break;
288  Offset = TableOffset + Length;
289  } else {
290  Rnglists.dump(OS, LookupPooledAddress, DumpOpts);
291  }
292  }
293 }
294 
297  const MCRegisterInfo *MRI,
298  Optional<uint64_t> DumpOffset) {
299  uint32_t Offset = 0;
300  DWARFDebugLoclists Loclists;
301 
302  DWARFListTableHeader Header(".debug_loclists", "locations");
303  if (Error E = Header.extract(Data, &Offset)) {
304  WithColor::error() << toString(std::move(E)) << '\n';
305  return;
306  }
307 
308  Header.dump(OS, DumpOpts);
309  DataExtractor LocData(Data.getData().drop_front(Offset),
310  Data.isLittleEndian(), Header.getAddrSize());
311 
312  Loclists.parse(LocData);
313  Loclists.dump(OS, 0, MRI, DumpOffset);
314 }
315 
317  raw_ostream &OS, DIDumpOptions DumpOpts,
318  std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
319 
320  Optional<uint64_t> DumpOffset;
321  uint64_t DumpType = DumpOpts.DumpType;
322 
323  StringRef Extension = sys::path::extension(DObj->getFileName());
324  bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
325 
326  // Print UUID header.
327  const auto *ObjFile = DObj->getFile();
328  if (DumpType & DIDT_UUID)
329  dumpUUID(OS, *ObjFile);
330 
331  // Print a header for each explicitly-requested section.
332  // Otherwise just print one for non-empty sections.
333  // Only print empty .dwo section headers when dumping a .dwo file.
334  bool Explicit = DumpType != DIDT_All && !IsDWO;
335  bool ExplicitDWO = Explicit && IsDWO;
336  auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
337  StringRef Section) {
338  DumpOffset = DumpOffsets[ID];
339  unsigned Mask = 1U << ID;
340  bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
341  if (Should)
342  OS << "\n" << Name << " contents:\n";
343  return Should;
344  };
345 
346  // Dump individual sections.
347  if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
348  DObj->getAbbrevSection()))
349  getDebugAbbrev()->dump(OS);
350  if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
351  DObj->getAbbrevDWOSection()))
352  getDebugAbbrevDWO()->dump(OS);
353 
354  auto dumpDebugInfo = [&](unit_iterator_range Units) {
355  if (DumpOffset)
356  getDIEForOffset(DumpOffset.getValue())
357  .dump(OS, 0, DumpOpts.noImplicitRecursion());
358  else
359  for (const auto &U : Units)
360  U->dump(OS, DumpOpts);
361  };
362  if (shouldDump(Explicit, ".debug_info", DIDT_ID_DebugInfo,
363  DObj->getInfoSection().Data))
364  dumpDebugInfo(info_section_units());
365  if (shouldDump(ExplicitDWO, ".debug_info.dwo", DIDT_ID_DebugInfo,
366  DObj->getInfoDWOSection().Data))
367  dumpDebugInfo(dwo_info_section_units());
368 
369  auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
370  OS << '\n' << Name << " contents:\n";
371  DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
372  for (const auto &U : Units)
373  if (DumpOffset)
374  U->getDIEForOffset(*DumpOffset)
375  .dump(OS, 0, DumpOpts.noImplicitRecursion());
376  else
377  U->dump(OS, DumpOpts);
378  };
379  if ((DumpType & DIDT_DebugTypes)) {
380  if (Explicit || getNumTypeUnits())
381  dumpDebugType(".debug_types", types_section_units());
382  if (ExplicitDWO || getNumDWOTypeUnits())
383  dumpDebugType(".debug_types.dwo", dwo_types_section_units());
384  }
385 
386  if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
387  DObj->getLocSection().Data)) {
388  getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
389  }
390  if (shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
391  DObj->getLoclistsSection().Data)) {
392  DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
393  0);
394  dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), DumpOffset);
395  }
396  if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
397  DObj->getLocDWOSection().Data)) {
398  getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOffset);
399  }
400 
401  if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
402  DObj->getDebugFrameSection()))
403  getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);
404 
405  if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
406  DObj->getEHFrameSection()))
407  getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);
408 
409  if (DumpType & DIDT_DebugMacro) {
410  if (Explicit || !getDebugMacro()->empty()) {
411  OS << "\n.debug_macinfo contents:\n";
412  getDebugMacro()->dump(OS);
413  }
414  }
415 
416  if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
417  DObj->getARangeSection())) {
418  uint32_t offset = 0;
419  DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
421  while (set.extract(arangesData, &offset))
422  set.dump(OS);
423  }
424 
425  auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
426  DIDumpOptions DumpOpts) {
427  while (!Parser.done()) {
428  if (DumpOffset && Parser.getOffset() != *DumpOffset) {
429  Parser.skip(dumpWarning);
430  continue;
431  }
432  OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
433  if (DumpOpts.Verbose) {
434  Parser.parseNext(dumpWarning, dumpWarning, &OS);
435  } else {
436  DWARFDebugLine::LineTable LineTable =
438  LineTable.dump(OS, DumpOpts);
439  }
440  }
441  };
442 
443  if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
444  DObj->getLineSection().Data)) {
445  DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
446  0);
447  DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
448  type_units());
449  DumpLineSection(Parser, DumpOpts);
450  }
451 
452  if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
453  DObj->getLineDWOSection().Data)) {
454  DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
455  isLittleEndian(), 0);
456  DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
457  dwo_type_units());
458  DumpLineSection(Parser, DumpOpts);
459  }
460 
461  if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
462  DObj->getCUIndexSection())) {
463  getCUIndex().dump(OS);
464  }
465 
466  if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
467  DObj->getTUIndexSection())) {
468  getTUIndex().dump(OS);
469  }
470 
471  if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
472  DObj->getStringSection())) {
473  DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
474  uint32_t offset = 0;
475  uint32_t strOffset = 0;
476  while (const char *s = strData.getCStr(&offset)) {
477  OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
478  strOffset = offset;
479  }
480  }
481  if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
482  DObj->getStringDWOSection())) {
483  DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
484  uint32_t offset = 0;
485  uint32_t strDWOOffset = 0;
486  while (const char *s = strDWOData.getCStr(&offset)) {
487  OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
488  strDWOOffset = offset;
489  }
490  }
491  if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
492  DObj->getLineStringSection())) {
493  DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
494  uint32_t offset = 0;
495  uint32_t strOffset = 0;
496  while (const char *s = strData.getCStr(&offset)) {
497  OS << format("0x%8.8x: \"", strOffset);
498  OS.write_escaped(s);
499  OS << "\"\n";
500  strOffset = offset;
501  }
502  }
503 
504  if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
505  DObj->getAddrSection().Data)) {
506  DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
507  isLittleEndian(), 0);
508  dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
509  }
510 
511  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
512  DObj->getRangeSection().Data)) {
513  uint8_t savedAddressByteSize = getCUAddrSize();
514  DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
515  isLittleEndian(), savedAddressByteSize);
516  uint32_t offset = 0;
517  DWARFDebugRangeList rangeList;
518  while (rangesData.isValidOffset(offset)) {
519  if (Error E = rangeList.extract(rangesData, &offset)) {
520  WithColor::error() << toString(std::move(E)) << '\n';
521  break;
522  }
523  rangeList.dump(OS);
524  }
525  }
526 
527  auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
528  const auto &CUs = compile_units();
529  auto I = CUs.begin();
530  if (I == CUs.end())
531  return None;
532  return (*I)->getAddrOffsetSectionItem(Index);
533  };
534 
535  if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
536  DObj->getRnglistsSection().Data)) {
537  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
538  isLittleEndian(), 0);
539  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
540  }
541 
542  if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
543  DObj->getRnglistsDWOSection().Data)) {
544  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
545  isLittleEndian(), 0);
546  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
547  }
548 
549  if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
550  DObj->getPubNamesSection()))
551  DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
552  .dump(OS);
553 
554  if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
555  DObj->getPubTypesSection()))
556  DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
557  .dump(OS);
558 
559  if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
560  DObj->getGnuPubNamesSection()))
561  DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
562  true /* GnuStyle */)
563  .dump(OS);
564 
565  if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
566  DObj->getGnuPubTypesSection()))
567  DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
568  true /* GnuStyle */)
569  .dump(OS);
570 
571  if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
572  DObj->getStringOffsetSection().Data))
573  dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
574  DObj->getStringOffsetSection(),
575  DObj->getStringSection(), normal_units(),
577  if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
578  DObj->getStringOffsetDWOSection().Data))
579  dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
580  DObj->getStringOffsetDWOSection(),
581  DObj->getStringDWOSection(), dwo_units(),
583 
584  if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
585  DObj->getGdbIndexSection())) {
586  getGdbIndex().dump(OS);
587  }
588 
589  if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
590  DObj->getAppleNamesSection().Data))
591  getAppleNames().dump(OS);
592 
593  if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
594  DObj->getAppleTypesSection().Data))
595  getAppleTypes().dump(OS);
596 
597  if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
598  DObj->getAppleNamespacesSection().Data))
599  getAppleNamespaces().dump(OS);
600 
601  if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
602  DObj->getAppleObjCSection().Data))
603  getAppleObjC().dump(OS);
604  if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
605  DObj->getDebugNamesSection().Data))
606  getDebugNames().dump(OS);
607 }
608 
610  parseDWOUnits(LazyParse);
611 
612  if (const auto &CUI = getCUIndex()) {
613  if (const auto *R = CUI.getFromHash(Hash))
614  return dyn_cast_or_null<DWARFCompileUnit>(
615  DWOUnits.getUnitForIndexEntry(*R));
616  return nullptr;
617  }
618 
619  // If there's no index, just search through the CUs in the DWO - there's
620  // probably only one unless this is something like LTO - though an in-process
621  // built/cached lookup table could be used in that case to improve repeated
622  // lookups of different CUs in the DWO.
623  for (const auto &DWOCU : dwo_compile_units()) {
624  // Might not have parsed DWO ID yet.
625  if (!DWOCU->getDWOId()) {
626  if (Optional<uint64_t> DWOId =
627  toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
628  DWOCU->setDWOId(*DWOId);
629  else
630  // No DWO ID?
631  continue;
632  }
633  if (DWOCU->getDWOId() == Hash)
634  return dyn_cast<DWARFCompileUnit>(DWOCU.get());
635  }
636  return nullptr;
637 }
638 
640  parseNormalUnits();
641  if (auto *CU = NormalUnits.getUnitForOffset(Offset))
642  return CU->getDIEForOffset(Offset);
643  return DWARFDie();
644 }
645 
647  bool Success = true;
648  DWARFVerifier verifier(OS, *this, DumpOpts);
649 
650  Success &= verifier.handleDebugAbbrev();
651  if (DumpOpts.DumpType & DIDT_DebugInfo)
652  Success &= verifier.handleDebugInfo();
653  if (DumpOpts.DumpType & DIDT_DebugLine)
654  Success &= verifier.handleDebugLine();
655  Success &= verifier.handleAccelTables();
656  return Success;
657 }
658 
660  if (CUIndex)
661  return *CUIndex;
662 
663  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
664 
665  CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
666  CUIndex->parse(CUIndexData);
667  return *CUIndex;
668 }
669 
671  if (TUIndex)
672  return *TUIndex;
673 
674  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
675 
676  TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
677  TUIndex->parse(TUIndexData);
678  return *TUIndex;
679 }
680 
682  if (GdbIndex)
683  return *GdbIndex;
684 
685  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
686  GdbIndex = llvm::make_unique<DWARFGdbIndex>();
687  GdbIndex->parse(GdbIndexData);
688  return *GdbIndex;
689 }
690 
692  if (Abbrev)
693  return Abbrev.get();
694 
695  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
696 
697  Abbrev.reset(new DWARFDebugAbbrev());
698  Abbrev->extract(abbrData);
699  return Abbrev.get();
700 }
701 
703  if (AbbrevDWO)
704  return AbbrevDWO.get();
705 
706  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
707  AbbrevDWO.reset(new DWARFDebugAbbrev());
708  AbbrevDWO->extract(abbrData);
709  return AbbrevDWO.get();
710 }
711 
713  if (Loc)
714  return Loc.get();
715 
716  Loc.reset(new DWARFDebugLoc);
717  // Assume all units have the same address byte size.
718  if (getNumCompileUnits()) {
719  DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
721  Loc->parse(LocData);
722  }
723  return Loc.get();
724 }
725 
727  if (LocDWO)
728  return LocDWO.get();
729 
730  LocDWO.reset(new DWARFDebugLoclists());
731  // Assume all compile units have the same address byte size.
732  // FIXME: We don't need AddressSize for split DWARF since relocatable
733  // addresses cannot appear there. At the moment DWARFExpression requires it.
734  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
735  LocDWO->parse(LocData);
736  return LocDWO.get();
737 }
738 
740  if (Aranges)
741  return Aranges.get();
742 
743  Aranges.reset(new DWARFDebugAranges());
744  Aranges->generate(this);
745  return Aranges.get();
746 }
747 
749  if (DebugFrame)
750  return DebugFrame.get();
751 
752  // There's a "bug" in the DWARFv3 standard with respect to the target address
753  // size within debug frame sections. While DWARF is supposed to be independent
754  // of its container, FDEs have fields with size being "target address size",
755  // which isn't specified in DWARF in general. It's only specified for CUs, but
756  // .eh_frame can appear without a .debug_info section. Follow the example of
757  // other tools (libdwarf) and extract this from the container (ObjectFile
758  // provides this information). This problem is fixed in DWARFv4
759  // See this dwarf-discuss discussion for more details:
760  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
761  DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
762  isLittleEndian(), DObj->getAddressSize());
763  DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
764  DebugFrame->parse(debugFrameData);
765  return DebugFrame.get();
766 }
767 
769  if (EHFrame)
770  return EHFrame.get();
771 
772  DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
773  DObj->getAddressSize());
774  DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
775  DebugFrame->parse(debugFrameData);
776  return DebugFrame.get();
777 }
778 
780  if (Macro)
781  return Macro.get();
782 
783  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
784  Macro.reset(new DWARFDebugMacro());
785  Macro->parse(MacinfoData);
786  return Macro.get();
787 }
788 
789 template <typename T>
790 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
791  const DWARFSection &Section, StringRef StringSection,
792  bool IsLittleEndian) {
793  if (Cache)
794  return *Cache;
795  DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
796  DataExtractor StrData(StringSection, IsLittleEndian, 0);
797  Cache.reset(new T(AccelSection, StrData));
798  if (Error E = Cache->extract())
799  llvm::consumeError(std::move(E));
800  return *Cache;
801 }
802 
804  return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
805  DObj->getStringSection(), isLittleEndian());
806 }
807 
809  return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
810  DObj->getStringSection(), isLittleEndian());
811 }
812 
814  return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
815  DObj->getStringSection(), isLittleEndian());
816 }
817 
819  return getAccelTable(AppleNamespaces, *DObj,
820  DObj->getAppleNamespacesSection(),
821  DObj->getStringSection(), isLittleEndian());
822 }
823 
825  return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
826  DObj->getStringSection(), isLittleEndian());
827 }
828 
833  if (!ExpectedLineTable) {
834  dumpWarning(ExpectedLineTable.takeError());
835  return nullptr;
836  }
837  return *ExpectedLineTable;
838 }
839 
841  DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
842  if (!Line)
843  Line.reset(new DWARFDebugLine);
844 
845  auto UnitDIE = U->getUnitDIE();
846  if (!UnitDIE)
847  return nullptr;
848 
849  auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
850  if (!Offset)
851  return nullptr; // No line table for this compile unit.
852 
853  uint32_t stmtOffset = *Offset + U->getLineTableOffset();
854  // See if the line table is cached.
855  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
856  return lt;
857 
858  // Make sure the offset is good before we try to parse.
859  if (stmtOffset >= U->getLineSection().Data.size())
860  return nullptr;
861 
862  // We have to parse it first.
863  DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
864  U->getAddressByteSize());
865  return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
866  RecoverableErrorCallback);
867 }
868 
869 void DWARFContext::parseNormalUnits() {
870  if (!NormalUnits.empty())
871  return;
872  NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
873  NormalUnits.finishedInfoUnits();
874  DObj->forEachTypesSections([&](const DWARFSection &S) {
875  NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
876  });
877 }
878 
879 void DWARFContext::parseDWOUnits(bool Lazy) {
880  if (!DWOUnits.empty())
881  return;
882  DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
883  Lazy);
884  DWOUnits.finishedInfoUnits();
885  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
886  DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
887  });
888 }
889 
891  parseNormalUnits();
892  return dyn_cast_or_null<DWARFCompileUnit>(
893  NormalUnits.getUnitForOffset(Offset));
894 }
895 
896 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
897  // First, get the offset of the compile unit.
898  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
899  // Retrieve the compile unit.
900  return getCompileUnitForOffset(CUOffset);
901 }
902 
905 
906  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
907  if (!CU)
908  return Result;
909 
910  Result.CompileUnit = CU;
911  Result.FunctionDIE = CU->getSubroutineForAddress(Address);
912 
913  std::vector<DWARFDie> Worklist;
914  Worklist.push_back(Result.FunctionDIE);
915  while (!Worklist.empty()) {
916  DWARFDie DIE = Worklist.back();
917  Worklist.pop_back();
918 
919  if (DIE.getTag() == DW_TAG_lexical_block &&
920  DIE.addressRangeContainsAddress(Address)) {
921  Result.BlockDIE = DIE;
922  break;
923  }
924 
925  for (auto Child : DIE)
926  Worklist.push_back(Child);
927  }
928 
929  return Result;
930 }
931 
933  uint64_t Address,
934  FunctionNameKind Kind,
935  std::string &FunctionName,
936  uint32_t &StartLine) {
937  // The address may correspond to instruction in some inlined function,
938  // so we have to build the chain of inlined functions and take the
939  // name of the topmost function in it.
940  SmallVector<DWARFDie, 4> InlinedChain;
941  CU->getInlinedChainForAddress(Address, InlinedChain);
942  if (InlinedChain.empty())
943  return false;
944 
945  const DWARFDie &DIE = InlinedChain[0];
946  bool FoundResult = false;
947  const char *Name = nullptr;
948  if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
949  FunctionName = Name;
950  FoundResult = true;
951  }
952  if (auto DeclLineResult = DIE.getDeclLine()) {
953  StartLine = DeclLineResult;
954  FoundResult = true;
955  }
956 
957  return FoundResult;
958 }
959 
961  DILineInfoSpecifier Spec) {
963 
964  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
965  if (!CU)
966  return Result;
968  Result.FunctionName,
969  Result.StartLine);
970  if (Spec.FLIKind != FileLineInfoKind::None) {
971  if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
972  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
973  Spec.FLIKind, Result);
974  }
975  return Result;
976 }
977 
980  DILineInfoSpecifier Spec) {
981  DILineInfoTable Lines;
982  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
983  if (!CU)
984  return Lines;
985 
986  std::string FunctionName = "<invalid>";
987  uint32_t StartLine = 0;
988  getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
989  StartLine);
990 
991  // If the Specifier says we don't need FileLineInfo, just
992  // return the top-most function at the starting address.
993  if (Spec.FLIKind == FileLineInfoKind::None) {
995  Result.FunctionName = FunctionName;
996  Result.StartLine = StartLine;
997  Lines.push_back(std::make_pair(Address, Result));
998  return Lines;
999  }
1000 
1001  const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1002 
1003  // Get the index of row we're looking for in the line table.
1004  std::vector<uint32_t> RowVector;
1005  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
1006  return Lines;
1007 
1008  for (uint32_t RowIndex : RowVector) {
1009  // Take file number and line/column from the row.
1010  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1012  LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1013  Spec.FLIKind, Result.FileName);
1014  Result.FunctionName = FunctionName;
1015  Result.Line = Row.Line;
1016  Result.Column = Row.Column;
1017  Result.StartLine = StartLine;
1018  Lines.push_back(std::make_pair(Row.Address, Result));
1019  }
1020 
1021  return Lines;
1022 }
1023 
1026  DILineInfoSpecifier Spec) {
1027  DIInliningInfo InliningInfo;
1028 
1029  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
1030  if (!CU)
1031  return InliningInfo;
1032 
1033  const DWARFLineTable *LineTable = nullptr;
1034  SmallVector<DWARFDie, 4> InlinedChain;
1035  CU->getInlinedChainForAddress(Address, InlinedChain);
1036  if (InlinedChain.size() == 0) {
1037  // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1038  // try to at least get file/line info from symbol table.
1039  if (Spec.FLIKind != FileLineInfoKind::None) {
1040  DILineInfo Frame;
1041  LineTable = getLineTableForUnit(CU);
1042  if (LineTable &&
1043  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1044  Spec.FLIKind, Frame))
1045  InliningInfo.addFrame(Frame);
1046  }
1047  return InliningInfo;
1048  }
1049 
1050  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1051  for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1052  DWARFDie &FunctionDIE = InlinedChain[i];
1053  DILineInfo Frame;
1054  // Get function name if necessary.
1055  if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1056  Frame.FunctionName = Name;
1057  if (auto DeclLineResult = FunctionDIE.getDeclLine())
1058  Frame.StartLine = DeclLineResult;
1059  if (Spec.FLIKind != FileLineInfoKind::None) {
1060  if (i == 0) {
1061  // For the topmost frame, initialize the line table of this
1062  // compile unit and fetch file/line info from it.
1063  LineTable = getLineTableForUnit(CU);
1064  // For the topmost routine, get file/line info from line table.
1065  if (LineTable)
1066  LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1067  Spec.FLIKind, Frame);
1068  } else {
1069  // Otherwise, use call file, call line and call column from
1070  // previous DIE in inlined chain.
1071  if (LineTable)
1072  LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1073  Spec.FLIKind, Frame.FileName);
1074  Frame.Line = CallLine;
1075  Frame.Column = CallColumn;
1076  Frame.Discriminator = CallDiscriminator;
1077  }
1078  // Get call file/line/column of a current DIE.
1079  if (i + 1 < n) {
1080  FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1081  CallDiscriminator);
1082  }
1083  }
1084  InliningInfo.addFrame(Frame);
1085  }
1086  return InliningInfo;
1087 }
1088 
1089 std::shared_ptr<DWARFContext>
1091  if (auto S = DWP.lock()) {
1092  DWARFContext *Ctxt = S->Context.get();
1093  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1094  }
1095 
1096  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1097 
1098  if (auto S = Entry->lock()) {
1099  DWARFContext *Ctxt = S->Context.get();
1100  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1101  }
1102 
1104  if (!CheckedForDWP) {
1105  SmallString<128> DWPName;
1107  this->DWPName.empty()
1108  ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
1109  : StringRef(this->DWPName));
1110  if (Obj) {
1111  Entry = &DWP;
1112  return Obj;
1113  } else {
1114  CheckedForDWP = true;
1115  // TODO: Should this error be handled (maybe in a high verbosity mode)
1116  // before falling back to .dwo files?
1117  consumeError(Obj.takeError());
1118  }
1119  }
1120 
1121  return object::ObjectFile::createObjectFile(AbsolutePath);
1122  }();
1123 
1124  if (!Obj) {
1125  // TODO: Actually report errors helpfully.
1126  consumeError(Obj.takeError());
1127  return nullptr;
1128  }
1129 
1130  auto S = std::make_shared<DWOFile>();
1131  S->File = std::move(Obj.get());
1132  S->Context = DWARFContext::create(*S->File.getBinary());
1133  *Entry = S;
1134  auto *Ctxt = S->Context.get();
1135  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1136 }
1137 
1138 static Error createError(const Twine &Reason, llvm::Error E) {
1139  return make_error<StringError>(Reason + toString(std::move(E)),
1141 }
1142 
1143 /// SymInfo contains information about symbol: it's address
1144 /// and section index which is -1LL for absolute symbols.
1145 struct SymInfo {
1146  uint64_t Address;
1147  uint64_t SectionIndex;
1148 };
1149 
1150 /// Returns the address of symbol relocation used against and a section index.
1151 /// Used for futher relocations computation. Symbol's section load address is
1153  const RelocationRef &Reloc,
1154  const LoadedObjectInfo *L,
1155  std::map<SymbolRef, SymInfo> &Cache) {
1156  SymInfo Ret = {0, (uint64_t)-1LL};
1158  object::symbol_iterator Sym = Reloc.getSymbol();
1159 
1160  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1161  // First calculate the address of the symbol or section as it appears
1162  // in the object file
1163  if (Sym != Obj.symbol_end()) {
1164  bool New;
1165  std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1166  if (!New)
1167  return CacheIt->second;
1168 
1169  Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1170  if (!SymAddrOrErr)
1171  return createError("failed to compute symbol address: ",
1172  SymAddrOrErr.takeError());
1173 
1174  // Also remember what section this symbol is in for later
1175  auto SectOrErr = Sym->getSection();
1176  if (!SectOrErr)
1177  return createError("failed to get symbol section: ",
1178  SectOrErr.takeError());
1179 
1180  RSec = *SectOrErr;
1181  Ret.Address = *SymAddrOrErr;
1182  } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1183  RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1184  Ret.Address = RSec->getAddress();
1185  }
1186 
1187  if (RSec != Obj.section_end())
1188  Ret.SectionIndex = RSec->getIndex();
1189 
1190  // If we are given load addresses for the sections, we need to adjust:
1191  // SymAddr = (Address of Symbol Or Section in File) -
1192  // (Address of Section in File) +
1193  // (Load Address of Section)
1194  // RSec is now either the section being targeted or the section
1195  // containing the symbol being targeted. In either case,
1196  // we need to perform the same computation.
1197  if (L && RSec != Obj.section_end())
1198  if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1199  Ret.Address += SectionLoadAddress - RSec->getAddress();
1200 
1201  if (CacheIt != Cache.end())
1202  CacheIt->second = Ret;
1203 
1204  return Ret;
1205 }
1206 
1207 static bool isRelocScattered(const object::ObjectFile &Obj,
1208  const RelocationRef &Reloc) {
1209  const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1210  if (!MachObj)
1211  return false;
1212  // MachO also has relocations that point to sections and
1213  // scattered relocations.
1214  auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1215  return MachObj->isRelocationScattered(RelocInfo);
1216 }
1217 
1219  WithColor::error() << toString(std::move(E)) << '\n';
1220  return ErrorPolicy::Continue;
1221 }
1222 
1223 namespace {
1224 struct DWARFSectionMap final : public DWARFSection {
1225  RelocAddrMap Relocs;
1226 };
1227 
1228 class DWARFObjInMemory final : public DWARFObject {
1229  bool IsLittleEndian;
1230  uint8_t AddressSize;
1231  StringRef FileName;
1232  const object::ObjectFile *Obj = nullptr;
1233  std::vector<SectionName> SectionNames;
1234 
1235  using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1236  std::map<object::SectionRef, unsigned>>;
1237 
1238  TypeSectionMap TypesSections;
1239  TypeSectionMap TypesDWOSections;
1240 
1241  DWARFSectionMap InfoSection;
1242  DWARFSectionMap LocSection;
1243  DWARFSectionMap LocListsSection;
1244  DWARFSectionMap LineSection;
1245  DWARFSectionMap RangeSection;
1246  DWARFSectionMap RnglistsSection;
1247  DWARFSectionMap StringOffsetSection;
1248  DWARFSectionMap InfoDWOSection;
1249  DWARFSectionMap LineDWOSection;
1250  DWARFSectionMap LocDWOSection;
1251  DWARFSectionMap StringOffsetDWOSection;
1252  DWARFSectionMap RangeDWOSection;
1253  DWARFSectionMap RnglistsDWOSection;
1254  DWARFSectionMap AddrSection;
1255  DWARFSectionMap AppleNamesSection;
1256  DWARFSectionMap AppleTypesSection;
1257  DWARFSectionMap AppleNamespacesSection;
1258  DWARFSectionMap AppleObjCSection;
1259  DWARFSectionMap DebugNamesSection;
1260 
1261  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1263  .Case("debug_info", &InfoSection)
1264  .Case("debug_loc", &LocSection)
1265  .Case("debug_loclists", &LocListsSection)
1266  .Case("debug_line", &LineSection)
1267  .Case("debug_str_offsets", &StringOffsetSection)
1268  .Case("debug_ranges", &RangeSection)
1269  .Case("debug_rnglists", &RnglistsSection)
1270  .Case("debug_info.dwo", &InfoDWOSection)
1271  .Case("debug_loc.dwo", &LocDWOSection)
1272  .Case("debug_line.dwo", &LineDWOSection)
1273  .Case("debug_names", &DebugNamesSection)
1274  .Case("debug_rnglists.dwo", &RnglistsDWOSection)
1275  .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1276  .Case("debug_addr", &AddrSection)
1277  .Case("apple_names", &AppleNamesSection)
1278  .Case("apple_types", &AppleTypesSection)
1279  .Case("apple_namespaces", &AppleNamespacesSection)
1280  .Case("apple_namespac", &AppleNamespacesSection)
1281  .Case("apple_objc", &AppleObjCSection)
1282  .Default(nullptr);
1283  }
1284 
1285  StringRef AbbrevSection;
1286  StringRef ARangeSection;
1287  StringRef DebugFrameSection;
1288  StringRef EHFrameSection;
1289  StringRef StringSection;
1290  StringRef MacinfoSection;
1291  StringRef PubNamesSection;
1292  StringRef PubTypesSection;
1293  StringRef GnuPubNamesSection;
1294  StringRef AbbrevDWOSection;
1295  StringRef StringDWOSection;
1296  StringRef GnuPubTypesSection;
1297  StringRef CUIndexSection;
1298  StringRef GdbIndexSection;
1299  StringRef TUIndexSection;
1300  StringRef LineStringSection;
1301 
1302  // A deque holding section data whose iterators are not invalidated when
1303  // new decompressed sections are inserted at the end.
1304  std::deque<SmallString<0>> UncompressedSections;
1305 
1306  StringRef *mapSectionToMember(StringRef Name) {
1307  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1308  return &Sec->Data;
1310  .Case("debug_abbrev", &AbbrevSection)
1311  .Case("debug_aranges", &ARangeSection)
1312  .Case("debug_frame", &DebugFrameSection)
1313  .Case("eh_frame", &EHFrameSection)
1314  .Case("debug_str", &StringSection)
1315  .Case("debug_macinfo", &MacinfoSection)
1316  .Case("debug_pubnames", &PubNamesSection)
1317  .Case("debug_pubtypes", &PubTypesSection)
1318  .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1319  .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1320  .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1321  .Case("debug_str.dwo", &StringDWOSection)
1322  .Case("debug_cu_index", &CUIndexSection)
1323  .Case("debug_tu_index", &TUIndexSection)
1324  .Case("gdb_index", &GdbIndexSection)
1325  .Case("debug_line_str", &LineStringSection)
1326  // Any more debug info sections go here.
1327  .Default(nullptr);
1328  }
1329 
1330  /// If Sec is compressed section, decompresses and updates its contents
1331  /// provided by Data. Otherwise leaves it unchanged.
1332  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1333  StringRef &Data) {
1334  if (!Decompressor::isCompressed(Sec))
1335  return Error::success();
1336 
1337  Expected<Decompressor> Decompressor =
1338  Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1339  if (!Decompressor)
1340  return Decompressor.takeError();
1341 
1342  SmallString<0> Out;
1343  if (auto Err = Decompressor->resizeAndDecompress(Out))
1344  return Err;
1345 
1346  UncompressedSections.push_back(std::move(Out));
1347  Data = UncompressedSections.back();
1348 
1349  return Error::success();
1350  }
1351 
1352 public:
1353  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1354  uint8_t AddrSize, bool IsLittleEndian)
1355  : IsLittleEndian(IsLittleEndian) {
1356  for (const auto &SecIt : Sections) {
1357  if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1358  *SectionData = SecIt.second->getBuffer();
1359  }
1360  }
1361  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1362  function_ref<ErrorPolicy(Error)> HandleError)
1363  : IsLittleEndian(Obj.isLittleEndian()),
1364  AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1365  Obj(&Obj) {
1366 
1367  StringMap<unsigned> SectionAmountMap;
1368  for (const SectionRef &Section : Obj.sections()) {
1369  StringRef Name;
1370  Section.getName(Name);
1371  ++SectionAmountMap[Name];
1372  SectionNames.push_back({ Name, true });
1373 
1374  // Skip BSS and Virtual sections, they aren't interesting.
1375  if (Section.isBSS() || Section.isVirtual())
1376  continue;
1377 
1378  // Skip sections stripped by dsymutil.
1379  if (Section.isStripped())
1380  continue;
1381 
1382  StringRef Data;
1383  section_iterator RelocatedSection = Section.getRelocatedSection();
1384  // Try to obtain an already relocated version of this section.
1385  // Else use the unrelocated section from the object file. We'll have to
1386  // apply relocations ourselves later.
1387  if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
1388  Section.getContents(Data);
1389 
1390  if (auto Err = maybeDecompress(Section, Name, Data)) {
1391  ErrorPolicy EP = HandleError(createError(
1392  "failed to decompress '" + Name + "', ", std::move(Err)));
1393  if (EP == ErrorPolicy::Halt)
1394  return;
1395  continue;
1396  }
1397 
1398  // Compressed sections names in GNU style starts from ".z",
1399  // at this point section is decompressed and we drop compression prefix.
1400  Name = Name.substr(
1401  Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1402 
1403  // Map platform specific debug section names to DWARF standard section
1404  // names.
1405  Name = Obj.mapDebugSectionName(Name);
1406 
1407  if (StringRef *SectionData = mapSectionToMember(Name)) {
1408  *SectionData = Data;
1409  if (Name == "debug_ranges") {
1410  // FIXME: Use the other dwo range section when we emit it.
1411  RangeDWOSection.Data = Data;
1412  }
1413  } else if (Name == "debug_types") {
1414  // Find debug_types data by section rather than name as there are
1415  // multiple, comdat grouped, debug_types sections.
1416  TypesSections[Section].Data = Data;
1417  } else if (Name == "debug_types.dwo") {
1418  TypesDWOSections[Section].Data = Data;
1419  }
1420 
1421  if (RelocatedSection == Obj.section_end())
1422  continue;
1423 
1424  StringRef RelSecName;
1425  StringRef RelSecData;
1426  RelocatedSection->getName(RelSecName);
1427 
1428  // If the section we're relocating was relocated already by the JIT,
1429  // then we used the relocated version above, so we do not need to process
1430  // relocations for it now.
1431  if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1432  continue;
1433 
1434  // In Mach-o files, the relocations do not need to be applied if
1435  // there is no load offset to apply. The value read at the
1436  // relocation point already factors in the section address
1437  // (actually applying the relocations will produce wrong results
1438  // as the section address will be added twice).
1439  if (!L && isa<MachOObjectFile>(&Obj))
1440  continue;
1441 
1442  RelSecName = RelSecName.substr(
1443  RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1444 
1445  // TODO: Add support for relocations in other sections as needed.
1446  // Record relocations for the debug_info and debug_line sections.
1447  DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1448  RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1449  if (!Map) {
1450  // Find debug_types relocs by section rather than name as there are
1451  // multiple, comdat grouped, debug_types sections.
1452  if (RelSecName == "debug_types")
1453  Map =
1454  &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1455  .Relocs;
1456  else if (RelSecName == "debug_types.dwo")
1457  Map = &static_cast<DWARFSectionMap &>(
1458  TypesDWOSections[*RelocatedSection])
1459  .Relocs;
1460  else
1461  continue;
1462  }
1463 
1464  if (Section.relocation_begin() == Section.relocation_end())
1465  continue;
1466 
1467  // Symbol to [address, section index] cache mapping.
1468  std::map<SymbolRef, SymInfo> AddrCache;
1469  for (const RelocationRef &Reloc : Section.relocations()) {
1470  // FIXME: it's not clear how to correctly handle scattered
1471  // relocations.
1472  if (isRelocScattered(Obj, Reloc))
1473  continue;
1474 
1475  Expected<SymInfo> SymInfoOrErr =
1476  getSymbolInfo(Obj, Reloc, L, AddrCache);
1477  if (!SymInfoOrErr) {
1478  if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1479  return;
1480  continue;
1481  }
1482 
1483  object::RelocVisitor V(Obj);
1484  uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1485  if (V.error()) {
1487  Reloc.getTypeName(Type);
1488  ErrorPolicy EP = HandleError(
1489  createError("failed to compute relocation: " + Type + ", ",
1490  errorCodeToError(object_error::parse_failed)));
1491  if (EP == ErrorPolicy::Halt)
1492  return;
1493  continue;
1494  }
1495  RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1496  Map->insert({Reloc.getOffset(), Rel});
1497  }
1498  }
1499 
1500  for (SectionName &S : SectionNames)
1501  if (SectionAmountMap[S.Name] > 1)
1502  S.IsNameUnique = false;
1503  }
1504 
1506  uint64_t Pos) const override {
1507  auto &Sec = static_cast<const DWARFSectionMap &>(S);
1508  RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1509  if (AI == Sec.Relocs.end())
1510  return None;
1511  return AI->second;
1512  }
1513 
1514  const object::ObjectFile *getFile() const override { return Obj; }
1515 
1516  ArrayRef<SectionName> getSectionNames() const override {
1517  return SectionNames;
1518  }
1519 
1520  bool isLittleEndian() const override { return IsLittleEndian; }
1521  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1522  const DWARFSection &getLineDWOSection() const override {
1523  return LineDWOSection;
1524  }
1525  const DWARFSection &getLocDWOSection() const override {
1526  return LocDWOSection;
1527  }
1528  StringRef getStringDWOSection() const override { return StringDWOSection; }
1529  const DWARFSection &getStringOffsetDWOSection() const override {
1530  return StringOffsetDWOSection;
1531  }
1532  const DWARFSection &getRangeDWOSection() const override {
1533  return RangeDWOSection;
1534  }
1535  const DWARFSection &getRnglistsDWOSection() const override {
1536  return RnglistsDWOSection;
1537  }
1538  const DWARFSection &getAddrSection() const override { return AddrSection; }
1539  StringRef getCUIndexSection() const override { return CUIndexSection; }
1540  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1541  StringRef getTUIndexSection() const override { return TUIndexSection; }
1542 
1543  // DWARF v5
1544  const DWARFSection &getStringOffsetSection() const override {
1545  return StringOffsetSection;
1546  }
1547  StringRef getLineStringSection() const override { return LineStringSection; }
1548 
1549  // Sections for DWARF5 split dwarf proposal.
1550  const DWARFSection &getInfoDWOSection() const override {
1551  return InfoDWOSection;
1552  }
1553  void forEachTypesDWOSections(
1554  function_ref<void(const DWARFSection &)> F) const override {
1555  for (auto &P : TypesDWOSections)
1556  F(P.second);
1557  }
1558 
1559  StringRef getAbbrevSection() const override { return AbbrevSection; }
1560  const DWARFSection &getLocSection() const override { return LocSection; }
1561  const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
1562  StringRef getARangeSection() const override { return ARangeSection; }
1563  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1564  StringRef getEHFrameSection() const override { return EHFrameSection; }
1565  const DWARFSection &getLineSection() const override { return LineSection; }
1566  StringRef getStringSection() const override { return StringSection; }
1567  const DWARFSection &getRangeSection() const override { return RangeSection; }
1568  const DWARFSection &getRnglistsSection() const override {
1569  return RnglistsSection;
1570  }
1571  StringRef getMacinfoSection() const override { return MacinfoSection; }
1572  StringRef getPubNamesSection() const override { return PubNamesSection; }
1573  StringRef getPubTypesSection() const override { return PubTypesSection; }
1574  StringRef getGnuPubNamesSection() const override {
1575  return GnuPubNamesSection;
1576  }
1577  StringRef getGnuPubTypesSection() const override {
1578  return GnuPubTypesSection;
1579  }
1580  const DWARFSection &getAppleNamesSection() const override {
1581  return AppleNamesSection;
1582  }
1583  const DWARFSection &getAppleTypesSection() const override {
1584  return AppleTypesSection;
1585  }
1586  const DWARFSection &getAppleNamespacesSection() const override {
1587  return AppleNamespacesSection;
1588  }
1589  const DWARFSection &getAppleObjCSection() const override {
1590  return AppleObjCSection;
1591  }
1592  const DWARFSection &getDebugNamesSection() const override {
1593  return DebugNamesSection;
1594  }
1595 
1596  StringRef getFileName() const override { return FileName; }
1597  uint8_t getAddressSize() const override { return AddressSize; }
1598  const DWARFSection &getInfoSection() const override { return InfoSection; }
1599  void forEachTypesSections(
1600  function_ref<void(const DWARFSection &)> F) const override {
1601  for (auto &P : TypesSections)
1602  F(P.second);
1603  }
1604 };
1605 } // namespace
1606 
1607 std::unique_ptr<DWARFContext>
1609  function_ref<ErrorPolicy(Error)> HandleError,
1610  std::string DWPName) {
1611  auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1612  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1613 }
1614 
1615 std::unique_ptr<DWARFContext>
1616 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1617  uint8_t AddrSize, bool isLittleEndian) {
1618  auto DObj =
1619  llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
1620  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
1621 }
1622 
1624  // Detect the architecture from the object file. We usually don't need OS
1625  // info to lookup a target and create register info.
1626  Triple TT;
1627  TT.setArch(Triple::ArchType(Obj.getArch()));
1630  std::string TargetLookupError;
1631  const Target *TheTarget =
1632  TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
1633  if (!TargetLookupError.empty())
1635  TargetLookupError.c_str());
1636  RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
1637  return Error::success();
1638 }
1639 
1641  // In theory, different compile units may have different address byte
1642  // sizes, but for simplicity we just use the address byte size of the
1643  // last compile unit. In practice the address size field is repeated across
1644  // various DWARF headers (at least in version 5) to make it easier to dump
1645  // them independently, not to enable varying the address size.
1646  uint8_t Addr = 0;
1647  for (const auto &CU : compile_units()) {
1648  Addr = CU->getAddressByteSize();
1649  break;
1650  }
1651  return Addr;
1652 }
1653 
1655  handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
1656  WithColor::warning() << Info.message() << '\n';
1657  });
1658 }
const DWARFUnitIndex & getTUIndex()
uint32_t StartLine
Definition: DIContext.h:37
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:153
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:647
const DWARFDebugFrame * getEHFrame()
Get a pointer to the parsed eh frame information object.
void push_back(const T &Elt)
Definition: SmallVector.h:218
uint32_t Discriminator
Definition: DIContext.h:40
const DWARFDebugFrame * getDebugFrame()
Get a pointer to the parsed frame information object.
unsigned getMaxDWOVersion()
Definition: DWARFContext.h:240
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian, unsigned MaxVersion)
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
Definition: raw_ostream.h:219
std::string FileName
Definition: DIContext.h:32
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const MCRegisterInfo *MRI, Optional< uint64_t > DumpOffset)
unit_iterator_range dwo_type_units()
Get type units in the DWO context.
Definition: DWARFContext.h:182
A parsed .debug_frame or .eh_frame section.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Represents structure for holding and parsing .debug_pub* tables.
A class representing the header of a list table such as the range list table in the ...
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:246
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:439
void setVendor(VendorType Kind)
setVendor - Set the vendor (second) component of the triple to a known type.
Definition: Triple.cpp:1152
StringRef getFileName() const
Definition: Binary.cpp:41
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
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
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition: WithColor.cpp:63
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:107
uint8_t getCUAddrSize()
Get address size from CUs.
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:190
virtual std::string message() const
Return the error message as a string.
Definition: Error.h:57
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition: WithColor.cpp:65
This class implements a map that also provides access to all stored values in a deterministic order...
Definition: MapVector.h:38
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
void parse(DataExtractor data)
unsigned getNumTypeUnits()
Get the number of type units in this context.
Definition: DWARFContext.h:197
StringRef getData() const
Get the data pointed to by this extractor.
Definition: DataExtractor.h:55
F(f)
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
Definition: DWARFContext.h:165
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract the table header and the array of offsets.
void setOS(OSType Kind)
setOS - Set the operating system (third) component of the triple to a known type. ...
Definition: Triple.cpp:1156
void addFrame(const DILineInfo &Frame)
Definition: DIContext.h:98
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:114
Error takeError()
Take ownership of the stored error.
Definition: Error.h:553
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Base class for error info classes.
Definition: Error.h:49
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
Definition: DWARFUnit.cpp:37
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
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:632
void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:196
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Definition: BitVector.h:938
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:963
DWARFCompileUnit * getCompileUnitForOffset(uint32_t Offset)
Return the compile unit that includes an offset (relative to .debug_info).
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)
static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
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:65
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
Definition: DWARFContext.h:159
const char * getCompilationDir()
Definition: DWARFUnit.cpp:328
FunctionNameKind FNKind
Definition: DIContext.h:123
A class representing an address table as specified in DWARF v5.
unsigned getNumCompileUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:191
const DWARFSection & getLineSection() const
Definition: DWARFUnit.h:289
unit_iterator_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:153
FileLineInfoKind FLIKind
Definition: DIContext.h:122
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:477
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const
Obtain the Load Address of a section by SectionRef.
Definition: DIContext.h:231
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
uint64_t Size
The contribution size not including the header.
Definition: DWARFUnit.h:167
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:337
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
Definition: DWARFContext.h:209
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:280
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
#define T
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:179
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:278
bool isLittleEndian() const
Get the endianness for this extractor.
Definition: DataExtractor.h:57
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:358
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:473
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:365
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, Optional< uint64_t > Offset) const
Dump the section data into the given stream.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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:154
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
Definition: DWARFContext.h:138
virtual StringRef mapDebugSectionName(StringRef Name) const
Maps a debug section name to a standard DWARF section name.
Definition: ObjectFile.h:303
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.
#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
unsigned getMaxVersion()
Definition: DWARFContext.h:234
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
Definition: DWARFContext.h:172
uint32_t Column
Definition: DIContext.h:36
unsigned const MachineRegisterInfo * MRI
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
const DWARFDebugLoclists * getDebugLocDWO()
Get a pointer to the parsed DebugLoc object.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
Controls which fields of DILineInfo container should be filled with data.
Definition: DIContext.h:118
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition: DIContext.h:175
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)
LineTable parseNext(function_ref< void(Error)> RecoverableErrorCallback, function_ref< void(Error)> UnrecoverableErrorCallback, raw_ostream *OS=nullptr)
Get the next line table from the section.
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:87
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro object.
A format-neutral container for inlined code description.
Definition: DIContext.h:78
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:250
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 void dumpWarning(Error Warning)
Dump Error as warning message to stderr.
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.
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize, std::function< void(Error)> WarnCallback)
Extract an entire table, including all addresses.
void dump(raw_ostream &OS)
virtual basic_symbol_iterator symbol_end() const =0
static void dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian)
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:53
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:349
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:978
size_t size() const
Definition: SmallVector.h:53
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:149
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1063
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
DWARFUnit * getUnitForOffset(uint32_t Offset) const
Definition: DWARFUnit.cpp:127
bool isLittleEndian() const
Definition: Binary.h:131
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...
const AppleAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Standard .debug_line state machine structure.
const AppleAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr, function_ref< ErrorPolicy(Error)> HandleError=defaultErrorHandler, std::string DWPName="")
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:972
DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E)
Definition: DWARFUnit.cpp:140
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
unit_iterator_range dwo_compile_units()
Get compile units in the DWO context.
Definition: DWARFContext.h:179
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:645
.debug_names section consists of one or more units.
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:905
uint16_t Column
An unsigned integer indicating a column number within a source line.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:381
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:969
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning &#39;\&#39;, &#39;&#39;, &#39; &#39;, &#39;"&#39;, and anything that doesn&#39;t satisfy llvm::isPrint into an escape...
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
unit_iterator_range type_units()
Get type units in this context.
Definition: DWARFContext.h:156
uint32_t getLength() const
Returns the length of this table, including the length field, or 0 if the length has not been determi...
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1023
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:35
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, DWARFSectionKind SectionKind, bool Lazy=false)
Read units from a .debug_info.dwo or .debug_types.dwo section.
Definition: DWARFUnit.cpp:48
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
void dump(raw_ostream &OS) const 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
virtual Triple::ArchType getArch() const =0
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:59
void dump(raw_ostream &OS, llvm::function_ref< Optional< SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
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:220
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:216
loop extract
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< Optional< SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
void dump(raw_ostream &OS) const
#define Success
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
Definition: DWARFContext.h:146
RelocAddrEntry contains relocated value and section index.
Definition: DWARFRelocMap.h:20
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ...
Definition: DWARFUnit.h:151
bool hasValue() const
Definition: Optional.h:183
const DWARFDebugNames & getDebugNames()
Get a reference to the parsed accelerator table object.
A class that verifies DWARF debug information given a DWARF Context.
Definition: DWARFVerifier.h:36
virtual section_iterator section_end() const =0
dwarf::Tag getTag() const
Definition: DWARFDie.h:72
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
const AppleAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
Wraps the returned DIEs for a given address.
Definition: DWARFContext.h:312
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
#define I(x, y, z)
Definition: MD5.cpp:58
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
unit_iterator_range dwo_units()
Get all units in the DWO context.
Definition: DWARFContext.h:185
const char * getCStr(uint32_t *offset_ptr) const
Extract a C string from *offset_ptr.
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
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
Definition: DWARFContext.h:215
uint32_t Size
Definition: Profile.cpp:47
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:330
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
const DWARFUnitIndex & getCUIndex()
void dump(raw_ostream &OS) const override
SymInfo contains information about symbol: it&#39;s address and section index which is -1LL for absolute ...
DINameKind FunctionNameKind
Definition: DIContext.h:120
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract an entire table, including all list entries.
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.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
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:46
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool hasValidLength() const
Verify that the given length is valid for this table.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
void skip(function_ref< void(Error)> ErrorCallback)
Skip the current line table and go to the following line table (if present) immediately.
Helper to allow for parsing of an entire .debug_line section in sequence.
const uint64_t Version
Definition: InstrProf.h:895
bool done() const
Indicates if the parser has parsed as much as possible.
uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value=0)
Definition: RelocVisitor.h:43
uint32_t getLineTableOffset() const
Definition: DWARFUnit.h:475
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:452
void setArch(ArchType Kind)
setArch - Set the architecture (first) component of the triple to a known type.
Definition: Triple.cpp:1148
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
uint32_t getOffset() const
Get the offset the parser has reached.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1158
Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr)
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
std::vector< Optional< StrOffsetsContributionDescriptor > > ContributionCollection
Base class for object file relocation visitors.
Definition: RelocVisitor.h:36
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
Definition: Path.cpp:605
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77