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