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  if (const auto &C = U->getStringOffsetsTableContribution())
105  Contributions.push_back(C);
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) {
162  << "overlapping contributions to string offsets table in 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).
273  raw_ostream &OS, DWARFDataExtractor &rnglistData,
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, Header.getVersion());
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  uint64_t DumpType = DumpOpts.DumpType;
321 
322  StringRef Extension = sys::path::extension(DObj->getFileName());
323  bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
324 
325  // Print UUID header.
326  const auto *ObjFile = DObj->getFile();
327  if (DumpType & DIDT_UUID)
328  dumpUUID(OS, *ObjFile);
329 
330  // Print a header for each explicitly-requested section.
331  // Otherwise just print one for non-empty sections.
332  // Only print empty .dwo section headers when dumping a .dwo file.
333  bool Explicit = DumpType != DIDT_All && !IsDWO;
334  bool ExplicitDWO = Explicit && IsDWO;
335  auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
337  unsigned Mask = 1U << ID;
338  bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
339  if (!Should)
340  return nullptr;
341  OS << "\n" << Name << " contents:\n";
342  return &DumpOffsets[ID];
343  };
344 
345  // Dump individual sections.
346  if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
347  DObj->getAbbrevSection()))
348  getDebugAbbrev()->dump(OS);
349  if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
350  DObj->getAbbrevDWOSection()))
351  getDebugAbbrevDWO()->dump(OS);
352 
353  auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
354  OS << '\n' << Name << " contents:\n";
355  if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
356  for (const auto &U : Units)
357  U->getDIEForOffset(DumpOffset.getValue())
358  .dump(OS, 0, DumpOpts.noImplicitRecursion());
359  else
360  for (const auto &U : Units)
361  U->dump(OS, DumpOpts);
362  };
363  if ((DumpType & DIDT_DebugInfo)) {
364  if (Explicit || getNumCompileUnits())
365  dumpDebugInfo(".debug_info", info_section_units());
366  if (ExplicitDWO || getNumDWOCompileUnits())
367  dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
368  }
369 
370  auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
371  OS << '\n' << Name << " contents:\n";
372  for (const auto &U : Units)
373  if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
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 (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
387  DObj->getLocSection().Data)) {
388  getDebugLoc()->dump(OS, getRegisterInfo(), *Off);
389  }
390  if (const auto *Off =
391  shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
392  DObj->getLoclistsSection().Data)) {
393  DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
394  0);
395  dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off);
396  }
397  if (const auto *Off =
398  shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
399  DObj->getLocDWOSection().Data)) {
400  getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off);
401  }
402 
403  if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
404  DObj->getDebugFrameSection()))
405  getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
406 
407  if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
408  DObj->getEHFrameSection()))
409  getEHFrame()->dump(OS, getRegisterInfo(), *Off);
410 
411  if (DumpType & DIDT_DebugMacro) {
412  if (Explicit || !getDebugMacro()->empty()) {
413  OS << "\n.debug_macinfo contents:\n";
414  getDebugMacro()->dump(OS);
415  }
416  }
417 
418  if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
419  DObj->getARangeSection())) {
420  uint32_t offset = 0;
421  DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
423  while (set.extract(arangesData, &offset))
424  set.dump(OS);
425  }
426 
427  auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
428  DIDumpOptions DumpOpts,
429  Optional<uint64_t> DumpOffset) {
430  while (!Parser.done()) {
431  if (DumpOffset && Parser.getOffset() != *DumpOffset) {
432  Parser.skip(dumpWarning);
433  continue;
434  }
435  OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
436  if (DumpOpts.Verbose) {
437  Parser.parseNext(dumpWarning, dumpWarning, &OS);
438  } else {
439  DWARFDebugLine::LineTable LineTable =
441  LineTable.dump(OS, DumpOpts);
442  }
443  }
444  };
445 
446  if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
447  DObj->getLineSection().Data)) {
448  DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
449  0);
450  DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
451  type_units());
452  DumpLineSection(Parser, DumpOpts, *Off);
453  }
454 
455  if (const auto *Off =
456  shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
457  DObj->getLineDWOSection().Data)) {
458  DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
459  isLittleEndian(), 0);
460  DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
461  dwo_type_units());
462  DumpLineSection(Parser, DumpOpts, *Off);
463  }
464 
465  if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
466  DObj->getCUIndexSection())) {
467  getCUIndex().dump(OS);
468  }
469 
470  if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
471  DObj->getTUIndexSection())) {
472  getTUIndex().dump(OS);
473  }
474 
475  if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
476  DObj->getStringSection())) {
477  DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
478  uint32_t offset = 0;
479  uint32_t strOffset = 0;
480  while (const char *s = strData.getCStr(&offset)) {
481  OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
482  strOffset = offset;
483  }
484  }
485  if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
486  DObj->getStringDWOSection())) {
487  DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
488  uint32_t offset = 0;
489  uint32_t strDWOOffset = 0;
490  while (const char *s = strDWOData.getCStr(&offset)) {
491  OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
492  strDWOOffset = offset;
493  }
494  }
495  if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
496  DObj->getLineStringSection())) {
497  DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
498  uint32_t offset = 0;
499  uint32_t strOffset = 0;
500  while (const char *s = strData.getCStr(&offset)) {
501  OS << format("0x%8.8x: \"", strOffset);
502  OS.write_escaped(s);
503  OS << "\"\n";
504  strOffset = offset;
505  }
506  }
507 
508  if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
509  DObj->getAddrSection().Data)) {
510  DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
511  isLittleEndian(), 0);
512  dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
513  }
514 
515  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
516  DObj->getRangeSection().Data)) {
517  uint8_t savedAddressByteSize = getCUAddrSize();
518  DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
519  isLittleEndian(), savedAddressByteSize);
520  uint32_t offset = 0;
521  DWARFDebugRangeList rangeList;
522  while (rangesData.isValidOffset(offset)) {
523  if (Error E = rangeList.extract(rangesData, &offset)) {
524  WithColor::error() << toString(std::move(E)) << '\n';
525  break;
526  }
527  rangeList.dump(OS);
528  }
529  }
530 
531  auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
532  const auto &CUs = compile_units();
533  auto I = CUs.begin();
534  if (I == CUs.end())
535  return None;
536  return (*I)->getAddrOffsetSectionItem(Index);
537  };
538 
539  if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
540  DObj->getRnglistsSection().Data)) {
541  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
542  isLittleEndian(), 0);
543  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
544  }
545 
546  if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
547  DObj->getRnglistsDWOSection().Data)) {
548  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
549  isLittleEndian(), 0);
550  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
551  }
552 
553  if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
554  DObj->getPubNamesSection().Data))
555  DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false)
556  .dump(OS);
557 
558  if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
559  DObj->getPubTypesSection().Data))
560  DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false)
561  .dump(OS);
562 
563  if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
564  DObj->getGnuPubNamesSection().Data))
565  DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(),
566  true /* GnuStyle */)
567  .dump(OS);
568 
569  if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
570  DObj->getGnuPubTypesSection().Data))
571  DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(),
572  true /* GnuStyle */)
573  .dump(OS);
574 
575  if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
576  DObj->getStringOffsetSection().Data))
577  dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
578  DObj->getStringOffsetSection(),
579  DObj->getStringSection(), normal_units(),
581  if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
582  DObj->getStringOffsetDWOSection().Data))
583  dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
584  DObj->getStringOffsetDWOSection(),
585  DObj->getStringDWOSection(), dwo_units(),
587 
588  if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
589  DObj->getGdbIndexSection())) {
590  getGdbIndex().dump(OS);
591  }
592 
593  if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
594  DObj->getAppleNamesSection().Data))
595  getAppleNames().dump(OS);
596 
597  if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
598  DObj->getAppleTypesSection().Data))
599  getAppleTypes().dump(OS);
600 
601  if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
602  DObj->getAppleNamespacesSection().Data))
603  getAppleNamespaces().dump(OS);
604 
605  if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
606  DObj->getAppleObjCSection().Data))
607  getAppleObjC().dump(OS);
608  if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
609  DObj->getDebugNamesSection().Data))
610  getDebugNames().dump(OS);
611 }
612 
614  parseDWOUnits(LazyParse);
615 
616  if (const auto &CUI = getCUIndex()) {
617  if (const auto *R = CUI.getFromHash(Hash))
618  return dyn_cast_or_null<DWARFCompileUnit>(
619  DWOUnits.getUnitForIndexEntry(*R));
620  return nullptr;
621  }
622 
623  // If there's no index, just search through the CUs in the DWO - there's
624  // probably only one unless this is something like LTO - though an in-process
625  // built/cached lookup table could be used in that case to improve repeated
626  // lookups of different CUs in the DWO.
627  for (const auto &DWOCU : dwo_compile_units()) {
628  // Might not have parsed DWO ID yet.
629  if (!DWOCU->getDWOId()) {
630  if (Optional<uint64_t> DWOId =
631  toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
632  DWOCU->setDWOId(*DWOId);
633  else
634  // No DWO ID?
635  continue;
636  }
637  if (DWOCU->getDWOId() == Hash)
638  return dyn_cast<DWARFCompileUnit>(DWOCU.get());
639  }
640  return nullptr;
641 }
642 
644  parseNormalUnits();
645  if (auto *CU = NormalUnits.getUnitForOffset(Offset))
646  return CU->getDIEForOffset(Offset);
647  return DWARFDie();
648 }
649 
651  bool Success = true;
652  DWARFVerifier verifier(OS, *this, DumpOpts);
653 
654  Success &= verifier.handleDebugAbbrev();
655  if (DumpOpts.DumpType & DIDT_DebugInfo)
656  Success &= verifier.handleDebugInfo();
657  if (DumpOpts.DumpType & DIDT_DebugLine)
658  Success &= verifier.handleDebugLine();
659  Success &= verifier.handleAccelTables();
660  return Success;
661 }
662 
664  if (CUIndex)
665  return *CUIndex;
666 
667  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
668 
669  CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
670  CUIndex->parse(CUIndexData);
671  return *CUIndex;
672 }
673 
675  if (TUIndex)
676  return *TUIndex;
677 
678  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
679 
680  TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
681  TUIndex->parse(TUIndexData);
682  return *TUIndex;
683 }
684 
686  if (GdbIndex)
687  return *GdbIndex;
688 
689  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
690  GdbIndex = llvm::make_unique<DWARFGdbIndex>();
691  GdbIndex->parse(GdbIndexData);
692  return *GdbIndex;
693 }
694 
696  if (Abbrev)
697  return Abbrev.get();
698 
699  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
700 
701  Abbrev.reset(new DWARFDebugAbbrev());
702  Abbrev->extract(abbrData);
703  return Abbrev.get();
704 }
705 
707  if (AbbrevDWO)
708  return AbbrevDWO.get();
709 
710  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
711  AbbrevDWO.reset(new DWARFDebugAbbrev());
712  AbbrevDWO->extract(abbrData);
713  return AbbrevDWO.get();
714 }
715 
717  if (Loc)
718  return Loc.get();
719 
720  Loc.reset(new DWARFDebugLoc);
721  // Assume all units have the same address byte size.
722  if (getNumCompileUnits()) {
723  DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
725  Loc->parse(LocData);
726  }
727  return Loc.get();
728 }
729 
731  if (LocDWO)
732  return LocDWO.get();
733 
734  LocDWO.reset(new DWARFDebugLoclists());
735  // Assume all compile units have the same address byte size.
736  // FIXME: We don't need AddressSize for split DWARF since relocatable
737  // addresses cannot appear there. At the moment DWARFExpression requires it.
738  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
739  // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
740  // that means we are parsing the new style .debug_loc (pre-standatized version
741  // of the .debug_loclists).
742  LocDWO->parse(LocData, 4 /* Version */);
743  return LocDWO.get();
744 }
745 
747  if (Aranges)
748  return Aranges.get();
749 
750  Aranges.reset(new DWARFDebugAranges());
751  Aranges->generate(this);
752  return Aranges.get();
753 }
754 
756  if (DebugFrame)
757  return DebugFrame.get();
758 
759  // There's a "bug" in the DWARFv3 standard with respect to the target address
760  // size within debug frame sections. While DWARF is supposed to be independent
761  // of its container, FDEs have fields with size being "target address size",
762  // which isn't specified in DWARF in general. It's only specified for CUs, but
763  // .eh_frame can appear without a .debug_info section. Follow the example of
764  // other tools (libdwarf) and extract this from the container (ObjectFile
765  // provides this information). This problem is fixed in DWARFv4
766  // See this dwarf-discuss discussion for more details:
767  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
768  DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
769  isLittleEndian(), DObj->getAddressSize());
770  DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
771  DebugFrame->parse(debugFrameData);
772  return DebugFrame.get();
773 }
774 
776  if (EHFrame)
777  return EHFrame.get();
778 
779  DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
780  DObj->getAddressSize());
781  DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
782  DebugFrame->parse(debugFrameData);
783  return DebugFrame.get();
784 }
785 
787  if (Macro)
788  return Macro.get();
789 
790  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
791  Macro.reset(new DWARFDebugMacro());
792  Macro->parse(MacinfoData);
793  return Macro.get();
794 }
795 
796 template <typename T>
797 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
798  const DWARFSection &Section, StringRef StringSection,
799  bool IsLittleEndian) {
800  if (Cache)
801  return *Cache;
802  DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
803  DataExtractor StrData(StringSection, IsLittleEndian, 0);
804  Cache.reset(new T(AccelSection, StrData));
805  if (Error E = Cache->extract())
806  llvm::consumeError(std::move(E));
807  return *Cache;
808 }
809 
811  return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
812  DObj->getStringSection(), isLittleEndian());
813 }
814 
816  return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
817  DObj->getStringSection(), isLittleEndian());
818 }
819 
821  return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
822  DObj->getStringSection(), isLittleEndian());
823 }
824 
826  return getAccelTable(AppleNamespaces, *DObj,
827  DObj->getAppleNamespacesSection(),
828  DObj->getStringSection(), isLittleEndian());
829 }
830 
832  return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
833  DObj->getStringSection(), isLittleEndian());
834 }
835 
840  if (!ExpectedLineTable) {
841  dumpWarning(ExpectedLineTable.takeError());
842  return nullptr;
843  }
844  return *ExpectedLineTable;
845 }
846 
848  DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
849  if (!Line)
850  Line.reset(new DWARFDebugLine);
851 
852  auto UnitDIE = U->getUnitDIE();
853  if (!UnitDIE)
854  return nullptr;
855 
856  auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
857  if (!Offset)
858  return nullptr; // No line table for this compile unit.
859 
860  uint32_t stmtOffset = *Offset + U->getLineTableOffset();
861  // See if the line table is cached.
862  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
863  return lt;
864 
865  // Make sure the offset is good before we try to parse.
866  if (stmtOffset >= U->getLineSection().Data.size())
867  return nullptr;
868 
869  // We have to parse it first.
870  DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
871  U->getAddressByteSize());
872  return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
873  RecoverableErrorCallback);
874 }
875 
876 void DWARFContext::parseNormalUnits() {
877  if (!NormalUnits.empty())
878  return;
879  DObj->forEachInfoSections([&](const DWARFSection &S) {
880  NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
881  });
882  NormalUnits.finishedInfoUnits();
883  DObj->forEachTypesSections([&](const DWARFSection &S) {
884  NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
885  });
886 }
887 
888 void DWARFContext::parseDWOUnits(bool Lazy) {
889  if (!DWOUnits.empty())
890  return;
891  DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
892  DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
893  });
894  DWOUnits.finishedInfoUnits();
895  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
896  DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
897  });
898 }
899 
901  parseNormalUnits();
902  return dyn_cast_or_null<DWARFCompileUnit>(
903  NormalUnits.getUnitForOffset(Offset));
904 }
905 
906 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
907  // First, get the offset of the compile unit.
908  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
909  // Retrieve the compile unit.
910  return getCompileUnitForOffset(CUOffset);
911 }
912 
914  DIEsForAddress Result;
915 
916  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
917  if (!CU)
918  return Result;
919 
920  Result.CompileUnit = CU;
921  Result.FunctionDIE = CU->getSubroutineForAddress(Address);
922 
923  std::vector<DWARFDie> Worklist;
924  Worklist.push_back(Result.FunctionDIE);
925  while (!Worklist.empty()) {
926  DWARFDie DIE = Worklist.back();
927  Worklist.pop_back();
928 
929  if (!DIE.isValid())
930  continue;
931 
932  if (DIE.getTag() == DW_TAG_lexical_block &&
933  DIE.addressRangeContainsAddress(Address)) {
934  Result.BlockDIE = DIE;
935  break;
936  }
937 
938  for (auto Child : DIE)
939  Worklist.push_back(Child);
940  }
941 
942  return Result;
943 }
944 
945 /// TODO: change input parameter from "uint64_t Address"
946 /// into "SectionedAddress Address"
948  uint64_t Address,
949  FunctionNameKind Kind,
950  std::string &FunctionName,
951  uint32_t &StartLine) {
952  // The address may correspond to instruction in some inlined function,
953  // so we have to build the chain of inlined functions and take the
954  // name of the topmost function in it.
955  SmallVector<DWARFDie, 4> InlinedChain;
956  CU->getInlinedChainForAddress(Address, InlinedChain);
957  if (InlinedChain.empty())
958  return false;
959 
960  const DWARFDie &DIE = InlinedChain[0];
961  bool FoundResult = false;
962  const char *Name = nullptr;
963  if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
964  FunctionName = Name;
965  FoundResult = true;
966  }
967  if (auto DeclLineResult = DIE.getDeclLine()) {
968  StartLine = DeclLineResult;
969  FoundResult = true;
970  }
971 
972  return FoundResult;
973 }
974 
976  DILineInfoSpecifier Spec) {
977  DILineInfo Result;
978 
979  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
980  if (!CU)
981  return Result;
982 
984  Result.FunctionName, Result.StartLine);
985  if (Spec.FLIKind != FileLineInfoKind::None) {
986  if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
987  LineTable->getFileLineInfoForAddress(
988  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
989  Spec.FLIKind, Result);
990  }
991  }
992  return Result;
993 }
994 
996  object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
997  DILineInfoTable Lines;
998  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
999  if (!CU)
1000  return Lines;
1001 
1002  std::string FunctionName = "<invalid>";
1003  uint32_t StartLine = 0;
1005  FunctionName, StartLine);
1006 
1007  // If the Specifier says we don't need FileLineInfo, just
1008  // return the top-most function at the starting address.
1009  if (Spec.FLIKind == FileLineInfoKind::None) {
1010  DILineInfo Result;
1011  Result.FunctionName = FunctionName;
1012  Result.StartLine = StartLine;
1013  Lines.push_back(std::make_pair(Address.Address, Result));
1014  return Lines;
1015  }
1016 
1017  const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1018 
1019  // Get the index of row we're looking for in the line table.
1020  std::vector<uint32_t> RowVector;
1021  if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1022  Size, RowVector)) {
1023  return Lines;
1024  }
1025 
1026  for (uint32_t RowIndex : RowVector) {
1027  // Take file number and line/column from the row.
1028  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1029  DILineInfo Result;
1030  LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1031  Spec.FLIKind, Result.FileName);
1032  Result.FunctionName = FunctionName;
1033  Result.Line = Row.Line;
1034  Result.Column = Row.Column;
1035  Result.StartLine = StartLine;
1036  Lines.push_back(std::make_pair(Row.Address.Address, Result));
1037  }
1038 
1039  return Lines;
1040 }
1041 
1044  DILineInfoSpecifier Spec) {
1045  DIInliningInfo InliningInfo;
1046 
1047  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1048  if (!CU)
1049  return InliningInfo;
1050 
1051  const DWARFLineTable *LineTable = nullptr;
1052  SmallVector<DWARFDie, 4> InlinedChain;
1053  CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1054  if (InlinedChain.size() == 0) {
1055  // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1056  // try to at least get file/line info from symbol table.
1057  if (Spec.FLIKind != FileLineInfoKind::None) {
1058  DILineInfo Frame;
1059  LineTable = getLineTableForUnit(CU);
1060  if (LineTable && LineTable->getFileLineInfoForAddress(
1061  {Address.Address, Address.SectionIndex},
1062  CU->getCompilationDir(), Spec.FLIKind, Frame))
1063  InliningInfo.addFrame(Frame);
1064  }
1065  return InliningInfo;
1066  }
1067 
1068  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1069  for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1070  DWARFDie &FunctionDIE = InlinedChain[i];
1071  DILineInfo Frame;
1072  // Get function name if necessary.
1073  if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1074  Frame.FunctionName = Name;
1075  if (auto DeclLineResult = FunctionDIE.getDeclLine())
1076  Frame.StartLine = DeclLineResult;
1077  if (Spec.FLIKind != FileLineInfoKind::None) {
1078  if (i == 0) {
1079  // For the topmost frame, initialize the line table of this
1080  // compile unit and fetch file/line info from it.
1081  LineTable = getLineTableForUnit(CU);
1082  // For the topmost routine, get file/line info from line table.
1083  if (LineTable)
1084  LineTable->getFileLineInfoForAddress(
1085  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1086  Spec.FLIKind, Frame);
1087  } else {
1088  // Otherwise, use call file, call line and call column from
1089  // previous DIE in inlined chain.
1090  if (LineTable)
1091  LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1092  Spec.FLIKind, Frame.FileName);
1093  Frame.Line = CallLine;
1094  Frame.Column = CallColumn;
1095  Frame.Discriminator = CallDiscriminator;
1096  }
1097  // Get call file/line/column of a current DIE.
1098  if (i + 1 < n) {
1099  FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1100  CallDiscriminator);
1101  }
1102  }
1103  InliningInfo.addFrame(Frame);
1104  }
1105  return InliningInfo;
1106 }
1107 
1108 std::shared_ptr<DWARFContext>
1110  if (auto S = DWP.lock()) {
1111  DWARFContext *Ctxt = S->Context.get();
1112  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1113  }
1114 
1115  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1116 
1117  if (auto S = Entry->lock()) {
1118  DWARFContext *Ctxt = S->Context.get();
1119  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1120  }
1121 
1123  if (!CheckedForDWP) {
1124  SmallString<128> DWPName;
1126  this->DWPName.empty()
1127  ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
1128  : StringRef(this->DWPName));
1129  if (Obj) {
1130  Entry = &DWP;
1131  return Obj;
1132  } else {
1133  CheckedForDWP = true;
1134  // TODO: Should this error be handled (maybe in a high verbosity mode)
1135  // before falling back to .dwo files?
1136  consumeError(Obj.takeError());
1137  }
1138  }
1139 
1140  return object::ObjectFile::createObjectFile(AbsolutePath);
1141  }();
1142 
1143  if (!Obj) {
1144  // TODO: Actually report errors helpfully.
1145  consumeError(Obj.takeError());
1146  return nullptr;
1147  }
1148 
1149  auto S = std::make_shared<DWOFile>();
1150  S->File = std::move(Obj.get());
1151  S->Context = DWARFContext::create(*S->File.getBinary());
1152  *Entry = S;
1153  auto *Ctxt = S->Context.get();
1154  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1155 }
1156 
1157 static Error createError(const Twine &Reason, llvm::Error E) {
1158  return make_error<StringError>(Reason + toString(std::move(E)),
1160 }
1161 
1162 /// SymInfo contains information about symbol: it's address
1163 /// and section index which is -1LL for absolute symbols.
1164 struct SymInfo {
1165  uint64_t Address;
1166  uint64_t SectionIndex;
1167 };
1168 
1169 /// Returns the address of symbol relocation used against and a section index.
1170 /// Used for futher relocations computation. Symbol's section load address is
1172  const RelocationRef &Reloc,
1173  const LoadedObjectInfo *L,
1174  std::map<SymbolRef, SymInfo> &Cache) {
1175  SymInfo Ret = {0, (uint64_t)-1LL};
1177  object::symbol_iterator Sym = Reloc.getSymbol();
1178 
1179  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1180  // First calculate the address of the symbol or section as it appears
1181  // in the object file
1182  if (Sym != Obj.symbol_end()) {
1183  bool New;
1184  std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1185  if (!New)
1186  return CacheIt->second;
1187 
1188  Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1189  if (!SymAddrOrErr)
1190  return createError("failed to compute symbol address: ",
1191  SymAddrOrErr.takeError());
1192 
1193  // Also remember what section this symbol is in for later
1194  auto SectOrErr = Sym->getSection();
1195  if (!SectOrErr)
1196  return createError("failed to get symbol section: ",
1197  SectOrErr.takeError());
1198 
1199  RSec = *SectOrErr;
1200  Ret.Address = *SymAddrOrErr;
1201  } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1202  RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1203  Ret.Address = RSec->getAddress();
1204  }
1205 
1206  if (RSec != Obj.section_end())
1207  Ret.SectionIndex = RSec->getIndex();
1208 
1209  // If we are given load addresses for the sections, we need to adjust:
1210  // SymAddr = (Address of Symbol Or Section in File) -
1211  // (Address of Section in File) +
1212  // (Load Address of Section)
1213  // RSec is now either the section being targeted or the section
1214  // containing the symbol being targeted. In either case,
1215  // we need to perform the same computation.
1216  if (L && RSec != Obj.section_end())
1217  if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1218  Ret.Address += SectionLoadAddress - RSec->getAddress();
1219 
1220  if (CacheIt != Cache.end())
1221  CacheIt->second = Ret;
1222 
1223  return Ret;
1224 }
1225 
1226 static bool isRelocScattered(const object::ObjectFile &Obj,
1227  const RelocationRef &Reloc) {
1228  const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1229  if (!MachObj)
1230  return false;
1231  // MachO also has relocations that point to sections and
1232  // scattered relocations.
1233  auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1234  return MachObj->isRelocationScattered(RelocInfo);
1235 }
1236 
1238  WithColor::error() << toString(std::move(E)) << '\n';
1239  return ErrorPolicy::Continue;
1240 }
1241 
1242 namespace {
1243 struct DWARFSectionMap final : public DWARFSection {
1244  RelocAddrMap Relocs;
1245 };
1246 
1247 class DWARFObjInMemory final : public DWARFObject {
1248  bool IsLittleEndian;
1249  uint8_t AddressSize;
1250  StringRef FileName;
1251  const object::ObjectFile *Obj = nullptr;
1252  std::vector<SectionName> SectionNames;
1253 
1254  using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1255  std::map<object::SectionRef, unsigned>>;
1256 
1257  InfoSectionMap InfoSections;
1258  InfoSectionMap TypesSections;
1259  InfoSectionMap InfoDWOSections;
1260  InfoSectionMap TypesDWOSections;
1261 
1262  DWARFSectionMap LocSection;
1263  DWARFSectionMap LocListsSection;
1264  DWARFSectionMap LineSection;
1265  DWARFSectionMap RangeSection;
1266  DWARFSectionMap RnglistsSection;
1267  DWARFSectionMap StringOffsetSection;
1268  DWARFSectionMap LineDWOSection;
1269  DWARFSectionMap LocDWOSection;
1270  DWARFSectionMap StringOffsetDWOSection;
1271  DWARFSectionMap RangeDWOSection;
1272  DWARFSectionMap RnglistsDWOSection;
1273  DWARFSectionMap AddrSection;
1274  DWARFSectionMap AppleNamesSection;
1275  DWARFSectionMap AppleTypesSection;
1276  DWARFSectionMap AppleNamespacesSection;
1277  DWARFSectionMap AppleObjCSection;
1278  DWARFSectionMap DebugNamesSection;
1279  DWARFSectionMap PubNamesSection;
1280  DWARFSectionMap PubTypesSection;
1281  DWARFSectionMap GnuPubNamesSection;
1282  DWARFSectionMap GnuPubTypesSection;
1283 
1284  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1286  .Case("debug_loc", &LocSection)
1287  .Case("debug_loclists", &LocListsSection)
1288  .Case("debug_line", &LineSection)
1289  .Case("debug_str_offsets", &StringOffsetSection)
1290  .Case("debug_ranges", &RangeSection)
1291  .Case("debug_rnglists", &RnglistsSection)
1292  .Case("debug_loc.dwo", &LocDWOSection)
1293  .Case("debug_line.dwo", &LineDWOSection)
1294  .Case("debug_names", &DebugNamesSection)
1295  .Case("debug_rnglists.dwo", &RnglistsDWOSection)
1296  .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1297  .Case("debug_addr", &AddrSection)
1298  .Case("apple_names", &AppleNamesSection)
1299  .Case("debug_pubnames", &PubNamesSection)
1300  .Case("debug_pubtypes", &PubTypesSection)
1301  .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1302  .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1303  .Case("apple_types", &AppleTypesSection)
1304  .Case("apple_namespaces", &AppleNamespacesSection)
1305  .Case("apple_namespac", &AppleNamespacesSection)
1306  .Case("apple_objc", &AppleObjCSection)
1307  .Default(nullptr);
1308  }
1309 
1310  StringRef AbbrevSection;
1311  StringRef ARangeSection;
1312  StringRef DebugFrameSection;
1313  StringRef EHFrameSection;
1314  StringRef StringSection;
1315  StringRef MacinfoSection;
1316  StringRef AbbrevDWOSection;
1317  StringRef StringDWOSection;
1318  StringRef CUIndexSection;
1319  StringRef GdbIndexSection;
1320  StringRef TUIndexSection;
1321  StringRef LineStringSection;
1322 
1323  // A deque holding section data whose iterators are not invalidated when
1324  // new decompressed sections are inserted at the end.
1325  std::deque<SmallString<0>> UncompressedSections;
1326 
1327  StringRef *mapSectionToMember(StringRef Name) {
1328  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1329  return &Sec->Data;
1331  .Case("debug_abbrev", &AbbrevSection)
1332  .Case("debug_aranges", &ARangeSection)
1333  .Case("debug_frame", &DebugFrameSection)
1334  .Case("eh_frame", &EHFrameSection)
1335  .Case("debug_str", &StringSection)
1336  .Case("debug_macinfo", &MacinfoSection)
1337  .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1338  .Case("debug_str.dwo", &StringDWOSection)
1339  .Case("debug_cu_index", &CUIndexSection)
1340  .Case("debug_tu_index", &TUIndexSection)
1341  .Case("gdb_index", &GdbIndexSection)
1342  .Case("debug_line_str", &LineStringSection)
1343  // Any more debug info sections go here.
1344  .Default(nullptr);
1345  }
1346 
1347  /// If Sec is compressed section, decompresses and updates its contents
1348  /// provided by Data. Otherwise leaves it unchanged.
1349  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1350  StringRef &Data) {
1351  if (!Decompressor::isCompressed(Sec))
1352  return Error::success();
1353 
1354  Expected<Decompressor> Decompressor =
1355  Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1356  if (!Decompressor)
1357  return Decompressor.takeError();
1358 
1359  SmallString<0> Out;
1360  if (auto Err = Decompressor->resizeAndDecompress(Out))
1361  return Err;
1362 
1363  UncompressedSections.push_back(std::move(Out));
1364  Data = UncompressedSections.back();
1365 
1366  return Error::success();
1367  }
1368 
1369 public:
1370  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1371  uint8_t AddrSize, bool IsLittleEndian)
1372  : IsLittleEndian(IsLittleEndian) {
1373  for (const auto &SecIt : Sections) {
1374  if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1375  *SectionData = SecIt.second->getBuffer();
1376  else if (SecIt.first() == "debug_info")
1377  // Find debug_info and debug_types data by section rather than name as
1378  // there are multiple, comdat grouped, of these sections.
1379  InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
1380  else if (SecIt.first() == "debug_info.dwo")
1381  InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1382  else if (SecIt.first() == "debug_types")
1383  TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
1384  else if (SecIt.first() == "debug_types.dwo")
1385  TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1386  }
1387  }
1388  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1389  function_ref<ErrorPolicy(Error)> HandleError)
1390  : IsLittleEndian(Obj.isLittleEndian()),
1391  AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1392  Obj(&Obj) {
1393 
1394  StringMap<unsigned> SectionAmountMap;
1395  for (const SectionRef &Section : Obj.sections()) {
1396  StringRef Name;
1397  Section.getName(Name);
1398  ++SectionAmountMap[Name];
1399  SectionNames.push_back({ Name, true });
1400 
1401  // Skip BSS and Virtual sections, they aren't interesting.
1402  if (Section.isBSS() || Section.isVirtual())
1403  continue;
1404 
1405  // Skip sections stripped by dsymutil.
1406  if (Section.isStripped())
1407  continue;
1408 
1409  StringRef Data;
1410  section_iterator RelocatedSection = Section.getRelocatedSection();
1411  // Try to obtain an already relocated version of this section.
1412  // Else use the unrelocated section from the object file. We'll have to
1413  // apply relocations ourselves later.
1414  if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
1415  Expected<StringRef> E = Section.getContents();
1416  if (E)
1417  Data = *E;
1418  else
1419  // maybeDecompress below will error.
1420  consumeError(E.takeError());
1421  }
1422 
1423  if (auto Err = maybeDecompress(Section, Name, Data)) {
1424  ErrorPolicy EP = HandleError(createError(
1425  "failed to decompress '" + Name + "', ", std::move(Err)));
1426  if (EP == ErrorPolicy::Halt)
1427  return;
1428  continue;
1429  }
1430 
1431  // Compressed sections names in GNU style starts from ".z",
1432  // at this point section is decompressed and we drop compression prefix.
1433  Name = Name.substr(
1434  Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1435 
1436  // Map platform specific debug section names to DWARF standard section
1437  // names.
1438  Name = Obj.mapDebugSectionName(Name);
1439 
1440  if (StringRef *SectionData = mapSectionToMember(Name)) {
1441  *SectionData = Data;
1442  if (Name == "debug_ranges") {
1443  // FIXME: Use the other dwo range section when we emit it.
1444  RangeDWOSection.Data = Data;
1445  }
1446  } else if (Name == "debug_info") {
1447  // Find debug_info and debug_types data by section rather than name as
1448  // there are multiple, comdat grouped, of these sections.
1449  InfoSections[Section].Data = Data;
1450  } else if (Name == "debug_info.dwo") {
1451  InfoDWOSections[Section].Data = Data;
1452  } else if (Name == "debug_types") {
1453  TypesSections[Section].Data = Data;
1454  } else if (Name == "debug_types.dwo") {
1455  TypesDWOSections[Section].Data = Data;
1456  }
1457 
1458  if (RelocatedSection == Obj.section_end())
1459  continue;
1460 
1461  StringRef RelSecName;
1462  StringRef RelSecData;
1463  RelocatedSection->getName(RelSecName);
1464 
1465  // If the section we're relocating was relocated already by the JIT,
1466  // then we used the relocated version above, so we do not need to process
1467  // relocations for it now.
1468  if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1469  continue;
1470 
1471  // In Mach-o files, the relocations do not need to be applied if
1472  // there is no load offset to apply. The value read at the
1473  // relocation point already factors in the section address
1474  // (actually applying the relocations will produce wrong results
1475  // as the section address will be added twice).
1476  if (!L && isa<MachOObjectFile>(&Obj))
1477  continue;
1478 
1479  RelSecName = RelSecName.substr(
1480  RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1481 
1482  // TODO: Add support for relocations in other sections as needed.
1483  // Record relocations for the debug_info and debug_line sections.
1484  DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1485  RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1486  if (!Map) {
1487  // Find debug_info and debug_types relocs by section rather than name
1488  // as there are multiple, comdat grouped, of these sections.
1489  if (RelSecName == "debug_info")
1490  Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
1491  .Relocs;
1492  else if (RelSecName == "debug_info.dwo")
1493  Map = &static_cast<DWARFSectionMap &>(
1494  InfoDWOSections[*RelocatedSection])
1495  .Relocs;
1496  else if (RelSecName == "debug_types")
1497  Map =
1498  &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1499  .Relocs;
1500  else if (RelSecName == "debug_types.dwo")
1501  Map = &static_cast<DWARFSectionMap &>(
1502  TypesDWOSections[*RelocatedSection])
1503  .Relocs;
1504  else
1505  continue;
1506  }
1507 
1508  if (Section.relocation_begin() == Section.relocation_end())
1509  continue;
1510 
1511  // Symbol to [address, section index] cache mapping.
1512  std::map<SymbolRef, SymInfo> AddrCache;
1513  bool (*Supports)(uint64_t);
1515  std::tie(Supports, Resolver) = getRelocationResolver(Obj);
1516  for (const RelocationRef &Reloc : Section.relocations()) {
1517  // FIXME: it's not clear how to correctly handle scattered
1518  // relocations.
1519  if (isRelocScattered(Obj, Reloc))
1520  continue;
1521 
1522  Expected<SymInfo> SymInfoOrErr =
1523  getSymbolInfo(Obj, Reloc, L, AddrCache);
1524  if (!SymInfoOrErr) {
1525  if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1526  return;
1527  continue;
1528  }
1529 
1530  // Check if Resolver can handle this relocation type early so as not to
1531  // handle invalid cases in DWARFDataExtractor.
1532  //
1533  // TODO Don't store Resolver in every RelocAddrEntry.
1534  if (Supports && Supports(Reloc.getType())) {
1535  Map->try_emplace(Reloc.getOffset(),
1536  RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc,
1537  Resolver, SymInfoOrErr->Address});
1538  } else {
1540  Reloc.getTypeName(Type);
1541  ErrorPolicy EP = HandleError(
1542  createError("failed to compute relocation: " + Type + ", ",
1543  errorCodeToError(object_error::parse_failed)));
1544  if (EP == ErrorPolicy::Halt)
1545  return;
1546  }
1547  }
1548  }
1549 
1550  for (SectionName &S : SectionNames)
1551  if (SectionAmountMap[S.Name] > 1)
1552  S.IsNameUnique = false;
1553  }
1554 
1556  uint64_t Pos) const override {
1557  auto &Sec = static_cast<const DWARFSectionMap &>(S);
1558  RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1559  if (AI == Sec.Relocs.end())
1560  return None;
1561  return AI->second;
1562  }
1563 
1564  const object::ObjectFile *getFile() const override { return Obj; }
1565 
1566  ArrayRef<SectionName> getSectionNames() const override {
1567  return SectionNames;
1568  }
1569 
1570  bool isLittleEndian() const override { return IsLittleEndian; }
1571  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1572  const DWARFSection &getLineDWOSection() const override {
1573  return LineDWOSection;
1574  }
1575  const DWARFSection &getLocDWOSection() const override {
1576  return LocDWOSection;
1577  }
1578  StringRef getStringDWOSection() const override { return StringDWOSection; }
1579  const DWARFSection &getStringOffsetDWOSection() const override {
1580  return StringOffsetDWOSection;
1581  }
1582  const DWARFSection &getRangeDWOSection() const override {
1583  return RangeDWOSection;
1584  }
1585  const DWARFSection &getRnglistsDWOSection() const override {
1586  return RnglistsDWOSection;
1587  }
1588  const DWARFSection &getAddrSection() const override { return AddrSection; }
1589  StringRef getCUIndexSection() const override { return CUIndexSection; }
1590  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1591  StringRef getTUIndexSection() const override { return TUIndexSection; }
1592 
1593  // DWARF v5
1594  const DWARFSection &getStringOffsetSection() const override {
1595  return StringOffsetSection;
1596  }
1597  StringRef getLineStringSection() const override { return LineStringSection; }
1598 
1599  // Sections for DWARF5 split dwarf proposal.
1600  void forEachInfoDWOSections(
1601  function_ref<void(const DWARFSection &)> F) const override {
1602  for (auto &P : InfoDWOSections)
1603  F(P.second);
1604  }
1605  void forEachTypesDWOSections(
1606  function_ref<void(const DWARFSection &)> F) const override {
1607  for (auto &P : TypesDWOSections)
1608  F(P.second);
1609  }
1610 
1611  StringRef getAbbrevSection() const override { return AbbrevSection; }
1612  const DWARFSection &getLocSection() const override { return LocSection; }
1613  const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
1614  StringRef getARangeSection() const override { return ARangeSection; }
1615  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1616  StringRef getEHFrameSection() const override { return EHFrameSection; }
1617  const DWARFSection &getLineSection() const override { return LineSection; }
1618  StringRef getStringSection() const override { return StringSection; }
1619  const DWARFSection &getRangeSection() const override { return RangeSection; }
1620  const DWARFSection &getRnglistsSection() const override {
1621  return RnglistsSection;
1622  }
1623  StringRef getMacinfoSection() const override { return MacinfoSection; }
1624  const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
1625  const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
1626  const DWARFSection &getGnuPubNamesSection() const override {
1627  return GnuPubNamesSection;
1628  }
1629  const DWARFSection &getGnuPubTypesSection() const override {
1630  return GnuPubTypesSection;
1631  }
1632  const DWARFSection &getAppleNamesSection() const override {
1633  return AppleNamesSection;
1634  }
1635  const DWARFSection &getAppleTypesSection() const override {
1636  return AppleTypesSection;
1637  }
1638  const DWARFSection &getAppleNamespacesSection() const override {
1639  return AppleNamespacesSection;
1640  }
1641  const DWARFSection &getAppleObjCSection() const override {
1642  return AppleObjCSection;
1643  }
1644  const DWARFSection &getDebugNamesSection() const override {
1645  return DebugNamesSection;
1646  }
1647 
1648  StringRef getFileName() const override { return FileName; }
1649  uint8_t getAddressSize() const override { return AddressSize; }
1650  void forEachInfoSections(
1651  function_ref<void(const DWARFSection &)> F) const override {
1652  for (auto &P : InfoSections)
1653  F(P.second);
1654  }
1655  void forEachTypesSections(
1656  function_ref<void(const DWARFSection &)> F) const override {
1657  for (auto &P : TypesSections)
1658  F(P.second);
1659  }
1660 };
1661 } // namespace
1662 
1663 std::unique_ptr<DWARFContext>
1665  function_ref<ErrorPolicy(Error)> HandleError,
1666  std::string DWPName) {
1667  auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1668  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1669 }
1670 
1671 std::unique_ptr<DWARFContext>
1672 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1673  uint8_t AddrSize, bool isLittleEndian) {
1674  auto DObj =
1675  llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
1676  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
1677 }
1678 
1680  // Detect the architecture from the object file. We usually don't need OS
1681  // info to lookup a target and create register info.
1682  Triple TT;
1683  TT.setArch(Triple::ArchType(Obj.getArch()));
1686  std::string TargetLookupError;
1687  const Target *TheTarget =
1688  TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
1689  if (!TargetLookupError.empty())
1691  TargetLookupError.c_str());
1692  RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
1693  return Error::success();
1694 }
1695 
1697  // In theory, different compile units may have different address byte
1698  // sizes, but for simplicity we just use the address byte size of the
1699  // last compile unit. In practice the address size field is repeated across
1700  // various DWARF headers (at least in version 5) to make it easier to dump
1701  // them independently, not to enable varying the address size.
1702  uint8_t Addr = 0;
1703  for (const auto &CU : compile_units()) {
1704  Addr = CU->getAddressByteSize();
1705  break;
1706  }
1707  return Addr;
1708 }
1709 
1711  handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
1712  WithColor::warning() << Info.message() << '\n';
1713  });
1714 }
const DWARFUnitIndex & getTUIndex()
uint64_t CallInst * C
uint32_t StartLine
Definition: DIContext.h:36
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:161
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:637
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)
bool isValid() const
Definition: DWARFDie.h:50
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:256
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
std::pair< bool(*)(uint64_t), RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
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:507
void setVendor(VendorType Kind)
setVendor - Set the vendor (second) component of the triple to a known type.
Definition: Triple.cpp:1170
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
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:226
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:1174
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:117
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< Optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
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.
bool getFileLineInfoForAddress(object::SectionedAddress Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
Fills the Result argument with the file and line information corresponding to Address.
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:622
void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, Optional< uint64_t > Offset) const
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
Definition: BitVector.h:937
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:966
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result) const
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)
TODO: change input parameter from "uint64_t Address" into "SectionedAddress Address".
Triple::ArchType getArch() const
Definition: DWARFContext.h:367
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:345
FunctionNameKind FNKind
Definition: DIContext.h:126
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:292
unit_iterator_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:152
FileLineInfoKind FLIKind
Definition: DIContext.h:125
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:545
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const
Obtain the Load Address of a section by SectionRef.
Definition: DIContext.h:241
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:171
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:341
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
Definition: DWARFContext.h:208
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:283
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
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:315
bool isLittleEndian() const
Get the endianness for this extractor.
Definition: DataExtractor.h:56
const std::string & str() const
Definition: Triple.h:364
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:541
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:400
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:157
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:335
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:121
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition: DIContext.h:180
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:700
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
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:1856
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)
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)
std::pair< llvm::MachO::Architecture, std::string > UUID
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:384
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:1213
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const
DWARFUnit * getUnitForOffset(uint32_t Offset) const
Definition: DWARFUnit.cpp:129
bool isLittleEndian() const
Definition: Binary.h:138
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:236
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:1122
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...
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
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
uint16_t Column
An unsigned integer indicating a column number within a source line.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:385
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:987
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:1173
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:837
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
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:226
void parse(DataExtractor data, unsigned Version)
void dump(raw_ostream &OS, llvm::function_ref< Optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
loop extract
void dump(raw_ostream &OS) const
#define Success
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:20
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ...
Definition: DWARFUnit.h:155
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:332
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
Definition: DWARFContext.h:214
DILineInfo getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
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="")
DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
bool isLittleEndian() const
Definition: DWARFContext.h:334
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:123
Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr)
Extract an entire table, including all list entries.
uint64_t(*)(RelocationRef R, uint64_t S, uint64_t A) RelocationResolver
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:984
bool done() const
Indicates if the parser has parsed as much as possible.
uint32_t getLineTableOffset() const
Definition: DWARFUnit.h:484
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:520
void setArch(ArchType Kind)
setArch - Set the architecture (first) component of the triple to a known type.
Definition: Triple.cpp:1166
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:81
std::vector< Optional< StrOffsetsContributionDescriptor > > ContributionCollection
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
Definition: Path.cpp:580
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77