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).
272  raw_ostream &OS, DWARFDataExtractor &rnglistData,
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.isValid())
929  continue;
930 
931  if (DIE.getTag() == DW_TAG_lexical_block &&
932  DIE.addressRangeContainsAddress(Address)) {
933  Result.BlockDIE = DIE;
934  break;
935  }
936 
937  for (auto Child : DIE)
938  Worklist.push_back(Child);
939  }
940 
941  return Result;
942 }
943 
944 /// TODO: change input parameter from "uint64_t Address"
945 /// into "SectionedAddress Address"
947  uint64_t Address,
948  FunctionNameKind Kind,
949  std::string &FunctionName,
950  uint32_t &StartLine) {
951  // The address may correspond to instruction in some inlined function,
952  // so we have to build the chain of inlined functions and take the
953  // name of the topmost function in it.
954  SmallVector<DWARFDie, 4> InlinedChain;
955  CU->getInlinedChainForAddress(Address, InlinedChain);
956  if (InlinedChain.empty())
957  return false;
958 
959  const DWARFDie &DIE = InlinedChain[0];
960  bool FoundResult = false;
961  const char *Name = nullptr;
962  if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
963  FunctionName = Name;
964  FoundResult = true;
965  }
966  if (auto DeclLineResult = DIE.getDeclLine()) {
967  StartLine = DeclLineResult;
968  FoundResult = true;
969  }
970 
971  return FoundResult;
972 }
973 
975  DILineInfoSpecifier Spec) {
976  DILineInfo Result;
977 
978  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
979  if (!CU)
980  return Result;
981 
983  Result.FunctionName, Result.StartLine);
984  if (Spec.FLIKind != FileLineInfoKind::None) {
985  if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
986  LineTable->getFileLineInfoForAddress(
987  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
988  Spec.FLIKind, Result);
989  }
990  }
991  return Result;
992 }
993 
995  object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
996  DILineInfoTable Lines;
997  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
998  if (!CU)
999  return Lines;
1000 
1001  std::string FunctionName = "<invalid>";
1002  uint32_t StartLine = 0;
1004  FunctionName, StartLine);
1005 
1006  // If the Specifier says we don't need FileLineInfo, just
1007  // return the top-most function at the starting address.
1008  if (Spec.FLIKind == FileLineInfoKind::None) {
1009  DILineInfo Result;
1010  Result.FunctionName = FunctionName;
1011  Result.StartLine = StartLine;
1012  Lines.push_back(std::make_pair(Address.Address, Result));
1013  return Lines;
1014  }
1015 
1016  const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1017 
1018  // Get the index of row we're looking for in the line table.
1019  std::vector<uint32_t> RowVector;
1020  if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1021  Size, RowVector)) {
1022  return Lines;
1023  }
1024 
1025  for (uint32_t RowIndex : RowVector) {
1026  // Take file number and line/column from the row.
1027  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1028  DILineInfo Result;
1029  LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1030  Spec.FLIKind, Result.FileName);
1031  Result.FunctionName = FunctionName;
1032  Result.Line = Row.Line;
1033  Result.Column = Row.Column;
1034  Result.StartLine = StartLine;
1035  Lines.push_back(std::make_pair(Row.Address.Address, Result));
1036  }
1037 
1038  return Lines;
1039 }
1040 
1043  DILineInfoSpecifier Spec) {
1044  DIInliningInfo InliningInfo;
1045 
1046  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1047  if (!CU)
1048  return InliningInfo;
1049 
1050  const DWARFLineTable *LineTable = nullptr;
1051  SmallVector<DWARFDie, 4> InlinedChain;
1052  CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1053  if (InlinedChain.size() == 0) {
1054  // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1055  // try to at least get file/line info from symbol table.
1056  if (Spec.FLIKind != FileLineInfoKind::None) {
1057  DILineInfo Frame;
1058  LineTable = getLineTableForUnit(CU);
1059  if (LineTable && LineTable->getFileLineInfoForAddress(
1060  {Address.Address, Address.SectionIndex},
1061  CU->getCompilationDir(), Spec.FLIKind, Frame))
1062  InliningInfo.addFrame(Frame);
1063  }
1064  return InliningInfo;
1065  }
1066 
1067  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1068  for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1069  DWARFDie &FunctionDIE = InlinedChain[i];
1070  DILineInfo Frame;
1071  // Get function name if necessary.
1072  if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1073  Frame.FunctionName = Name;
1074  if (auto DeclLineResult = FunctionDIE.getDeclLine())
1075  Frame.StartLine = DeclLineResult;
1076  if (Spec.FLIKind != FileLineInfoKind::None) {
1077  if (i == 0) {
1078  // For the topmost frame, initialize the line table of this
1079  // compile unit and fetch file/line info from it.
1080  LineTable = getLineTableForUnit(CU);
1081  // For the topmost routine, get file/line info from line table.
1082  if (LineTable)
1083  LineTable->getFileLineInfoForAddress(
1084  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1085  Spec.FLIKind, Frame);
1086  } else {
1087  // Otherwise, use call file, call line and call column from
1088  // previous DIE in inlined chain.
1089  if (LineTable)
1090  LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1091  Spec.FLIKind, Frame.FileName);
1092  Frame.Line = CallLine;
1093  Frame.Column = CallColumn;
1094  Frame.Discriminator = CallDiscriminator;
1095  }
1096  // Get call file/line/column of a current DIE.
1097  if (i + 1 < n) {
1098  FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1099  CallDiscriminator);
1100  }
1101  }
1102  InliningInfo.addFrame(Frame);
1103  }
1104  return InliningInfo;
1105 }
1106 
1107 std::shared_ptr<DWARFContext>
1109  if (auto S = DWP.lock()) {
1110  DWARFContext *Ctxt = S->Context.get();
1111  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1112  }
1113 
1114  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1115 
1116  if (auto S = Entry->lock()) {
1117  DWARFContext *Ctxt = S->Context.get();
1118  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1119  }
1120 
1122  if (!CheckedForDWP) {
1123  SmallString<128> DWPName;
1125  this->DWPName.empty()
1126  ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
1127  : StringRef(this->DWPName));
1128  if (Obj) {
1129  Entry = &DWP;
1130  return Obj;
1131  } else {
1132  CheckedForDWP = true;
1133  // TODO: Should this error be handled (maybe in a high verbosity mode)
1134  // before falling back to .dwo files?
1135  consumeError(Obj.takeError());
1136  }
1137  }
1138 
1139  return object::ObjectFile::createObjectFile(AbsolutePath);
1140  }();
1141 
1142  if (!Obj) {
1143  // TODO: Actually report errors helpfully.
1144  consumeError(Obj.takeError());
1145  return nullptr;
1146  }
1147 
1148  auto S = std::make_shared<DWOFile>();
1149  S->File = std::move(Obj.get());
1150  S->Context = DWARFContext::create(*S->File.getBinary());
1151  *Entry = S;
1152  auto *Ctxt = S->Context.get();
1153  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1154 }
1155 
1156 static Error createError(const Twine &Reason, llvm::Error E) {
1157  return make_error<StringError>(Reason + toString(std::move(E)),
1159 }
1160 
1161 /// SymInfo contains information about symbol: it's address
1162 /// and section index which is -1LL for absolute symbols.
1163 struct SymInfo {
1164  uint64_t Address;
1165  uint64_t SectionIndex;
1166 };
1167 
1168 /// Returns the address of symbol relocation used against and a section index.
1169 /// Used for futher relocations computation. Symbol's section load address is
1171  const RelocationRef &Reloc,
1172  const LoadedObjectInfo *L,
1173  std::map<SymbolRef, SymInfo> &Cache) {
1174  SymInfo Ret = {0, (uint64_t)-1LL};
1176  object::symbol_iterator Sym = Reloc.getSymbol();
1177 
1178  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1179  // First calculate the address of the symbol or section as it appears
1180  // in the object file
1181  if (Sym != Obj.symbol_end()) {
1182  bool New;
1183  std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1184  if (!New)
1185  return CacheIt->second;
1186 
1187  Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1188  if (!SymAddrOrErr)
1189  return createError("failed to compute symbol address: ",
1190  SymAddrOrErr.takeError());
1191 
1192  // Also remember what section this symbol is in for later
1193  auto SectOrErr = Sym->getSection();
1194  if (!SectOrErr)
1195  return createError("failed to get symbol section: ",
1196  SectOrErr.takeError());
1197 
1198  RSec = *SectOrErr;
1199  Ret.Address = *SymAddrOrErr;
1200  } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1201  RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1202  Ret.Address = RSec->getAddress();
1203  }
1204 
1205  if (RSec != Obj.section_end())
1206  Ret.SectionIndex = RSec->getIndex();
1207 
1208  // If we are given load addresses for the sections, we need to adjust:
1209  // SymAddr = (Address of Symbol Or Section in File) -
1210  // (Address of Section in File) +
1211  // (Load Address of Section)
1212  // RSec is now either the section being targeted or the section
1213  // containing the symbol being targeted. In either case,
1214  // we need to perform the same computation.
1215  if (L && RSec != Obj.section_end())
1216  if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1217  Ret.Address += SectionLoadAddress - RSec->getAddress();
1218 
1219  if (CacheIt != Cache.end())
1220  CacheIt->second = Ret;
1221 
1222  return Ret;
1223 }
1224 
1225 static bool isRelocScattered(const object::ObjectFile &Obj,
1226  const RelocationRef &Reloc) {
1227  const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1228  if (!MachObj)
1229  return false;
1230  // MachO also has relocations that point to sections and
1231  // scattered relocations.
1232  auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1233  return MachObj->isRelocationScattered(RelocInfo);
1234 }
1235 
1237  WithColor::error() << toString(std::move(E)) << '\n';
1238  return ErrorPolicy::Continue;
1239 }
1240 
1241 namespace {
1242 struct DWARFSectionMap final : public DWARFSection {
1243  RelocAddrMap Relocs;
1244 };
1245 
1246 class DWARFObjInMemory final : public DWARFObject {
1247  bool IsLittleEndian;
1248  uint8_t AddressSize;
1249  StringRef FileName;
1250  const object::ObjectFile *Obj = nullptr;
1251  std::vector<SectionName> SectionNames;
1252 
1253  using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1254  std::map<object::SectionRef, unsigned>>;
1255 
1256  InfoSectionMap InfoSections;
1257  InfoSectionMap TypesSections;
1258  InfoSectionMap InfoDWOSections;
1259  InfoSectionMap TypesDWOSections;
1260 
1261  DWARFSectionMap LocSection;
1262  DWARFSectionMap LocListsSection;
1263  DWARFSectionMap LineSection;
1264  DWARFSectionMap RangeSection;
1265  DWARFSectionMap RnglistsSection;
1266  DWARFSectionMap StringOffsetSection;
1267  DWARFSectionMap LineDWOSection;
1268  DWARFSectionMap LocDWOSection;
1269  DWARFSectionMap StringOffsetDWOSection;
1270  DWARFSectionMap RangeDWOSection;
1271  DWARFSectionMap RnglistsDWOSection;
1272  DWARFSectionMap AddrSection;
1273  DWARFSectionMap AppleNamesSection;
1274  DWARFSectionMap AppleTypesSection;
1275  DWARFSectionMap AppleNamespacesSection;
1276  DWARFSectionMap AppleObjCSection;
1277  DWARFSectionMap DebugNamesSection;
1278  DWARFSectionMap PubNamesSection;
1279  DWARFSectionMap PubTypesSection;
1280  DWARFSectionMap GnuPubNamesSection;
1281  DWARFSectionMap GnuPubTypesSection;
1282 
1283  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1285  .Case("debug_loc", &LocSection)
1286  .Case("debug_loclists", &LocListsSection)
1287  .Case("debug_line", &LineSection)
1288  .Case("debug_str_offsets", &StringOffsetSection)
1289  .Case("debug_ranges", &RangeSection)
1290  .Case("debug_rnglists", &RnglistsSection)
1291  .Case("debug_loc.dwo", &LocDWOSection)
1292  .Case("debug_line.dwo", &LineDWOSection)
1293  .Case("debug_names", &DebugNamesSection)
1294  .Case("debug_rnglists.dwo", &RnglistsDWOSection)
1295  .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1296  .Case("debug_addr", &AddrSection)
1297  .Case("apple_names", &AppleNamesSection)
1298  .Case("debug_pubnames", &PubNamesSection)
1299  .Case("debug_pubtypes", &PubTypesSection)
1300  .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1301  .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1302  .Case("apple_types", &AppleTypesSection)
1303  .Case("apple_namespaces", &AppleNamespacesSection)
1304  .Case("apple_namespac", &AppleNamespacesSection)
1305  .Case("apple_objc", &AppleObjCSection)
1306  .Default(nullptr);
1307  }
1308 
1309  StringRef AbbrevSection;
1310  StringRef ARangeSection;
1311  StringRef DebugFrameSection;
1312  StringRef EHFrameSection;
1313  StringRef StringSection;
1314  StringRef MacinfoSection;
1315  StringRef AbbrevDWOSection;
1316  StringRef StringDWOSection;
1317  StringRef CUIndexSection;
1318  StringRef GdbIndexSection;
1319  StringRef TUIndexSection;
1320  StringRef LineStringSection;
1321 
1322  // A deque holding section data whose iterators are not invalidated when
1323  // new decompressed sections are inserted at the end.
1324  std::deque<SmallString<0>> UncompressedSections;
1325 
1326  StringRef *mapSectionToMember(StringRef Name) {
1327  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1328  return &Sec->Data;
1330  .Case("debug_abbrev", &AbbrevSection)
1331  .Case("debug_aranges", &ARangeSection)
1332  .Case("debug_frame", &DebugFrameSection)
1333  .Case("eh_frame", &EHFrameSection)
1334  .Case("debug_str", &StringSection)
1335  .Case("debug_macinfo", &MacinfoSection)
1336  .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1337  .Case("debug_str.dwo", &StringDWOSection)
1338  .Case("debug_cu_index", &CUIndexSection)
1339  .Case("debug_tu_index", &TUIndexSection)
1340  .Case("gdb_index", &GdbIndexSection)
1341  .Case("debug_line_str", &LineStringSection)
1342  // Any more debug info sections go here.
1343  .Default(nullptr);
1344  }
1345 
1346  /// If Sec is compressed section, decompresses and updates its contents
1347  /// provided by Data. Otherwise leaves it unchanged.
1348  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1349  StringRef &Data) {
1350  if (!Decompressor::isCompressed(Sec))
1351  return Error::success();
1352 
1353  Expected<Decompressor> Decompressor =
1354  Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1355  if (!Decompressor)
1356  return Decompressor.takeError();
1357 
1358  SmallString<0> Out;
1359  if (auto Err = Decompressor->resizeAndDecompress(Out))
1360  return Err;
1361 
1362  UncompressedSections.push_back(std::move(Out));
1363  Data = UncompressedSections.back();
1364 
1365  return Error::success();
1366  }
1367 
1368 public:
1369  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1370  uint8_t AddrSize, bool IsLittleEndian)
1371  : IsLittleEndian(IsLittleEndian) {
1372  for (const auto &SecIt : Sections) {
1373  if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1374  *SectionData = SecIt.second->getBuffer();
1375  else if (SecIt.first() == "debug_info")
1376  // Find debug_info and debug_types data by section rather than name as
1377  // there are multiple, comdat grouped, of these sections.
1378  InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
1379  else if (SecIt.first() == "debug_info.dwo")
1380  InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1381  else if (SecIt.first() == "debug_types")
1382  TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
1383  else if (SecIt.first() == "debug_types.dwo")
1384  TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1385  }
1386  }
1387  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1388  function_ref<ErrorPolicy(Error)> HandleError)
1389  : IsLittleEndian(Obj.isLittleEndian()),
1390  AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1391  Obj(&Obj) {
1392 
1393  StringMap<unsigned> SectionAmountMap;
1394  for (const SectionRef &Section : Obj.sections()) {
1395  StringRef Name;
1396  Section.getName(Name);
1397  ++SectionAmountMap[Name];
1398  SectionNames.push_back({ Name, true });
1399 
1400  // Skip BSS and Virtual sections, they aren't interesting.
1401  if (Section.isBSS() || Section.isVirtual())
1402  continue;
1403 
1404  // Skip sections stripped by dsymutil.
1405  if (Section.isStripped())
1406  continue;
1407 
1408  StringRef Data;
1409  section_iterator RelocatedSection = Section.getRelocatedSection();
1410  // Try to obtain an already relocated version of this section.
1411  // Else use the unrelocated section from the object file. We'll have to
1412  // apply relocations ourselves later.
1413  if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
1414  Expected<StringRef> E = Section.getContents();
1415  if (E)
1416  Data = *E;
1417  else
1418  // maybeDecompress below will error.
1419  consumeError(E.takeError());
1420  }
1421 
1422  if (auto Err = maybeDecompress(Section, Name, Data)) {
1423  ErrorPolicy EP = HandleError(createError(
1424  "failed to decompress '" + Name + "', ", std::move(Err)));
1425  if (EP == ErrorPolicy::Halt)
1426  return;
1427  continue;
1428  }
1429 
1430  // Compressed sections names in GNU style starts from ".z",
1431  // at this point section is decompressed and we drop compression prefix.
1432  Name = Name.substr(
1433  Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1434 
1435  // Map platform specific debug section names to DWARF standard section
1436  // names.
1437  Name = Obj.mapDebugSectionName(Name);
1438 
1439  if (StringRef *SectionData = mapSectionToMember(Name)) {
1440  *SectionData = Data;
1441  if (Name == "debug_ranges") {
1442  // FIXME: Use the other dwo range section when we emit it.
1443  RangeDWOSection.Data = Data;
1444  }
1445  } else if (Name == "debug_info") {
1446  // Find debug_info and debug_types data by section rather than name as
1447  // there are multiple, comdat grouped, of these sections.
1448  InfoSections[Section].Data = Data;
1449  } else if (Name == "debug_info.dwo") {
1450  InfoDWOSections[Section].Data = Data;
1451  } else if (Name == "debug_types") {
1452  TypesSections[Section].Data = Data;
1453  } else if (Name == "debug_types.dwo") {
1454  TypesDWOSections[Section].Data = Data;
1455  }
1456 
1457  if (RelocatedSection == Obj.section_end())
1458  continue;
1459 
1460  StringRef RelSecName;
1461  StringRef RelSecData;
1462  RelocatedSection->getName(RelSecName);
1463 
1464  // If the section we're relocating was relocated already by the JIT,
1465  // then we used the relocated version above, so we do not need to process
1466  // relocations for it now.
1467  if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1468  continue;
1469 
1470  // In Mach-o files, the relocations do not need to be applied if
1471  // there is no load offset to apply. The value read at the
1472  // relocation point already factors in the section address
1473  // (actually applying the relocations will produce wrong results
1474  // as the section address will be added twice).
1475  if (!L && isa<MachOObjectFile>(&Obj))
1476  continue;
1477 
1478  RelSecName = RelSecName.substr(
1479  RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1480 
1481  // TODO: Add support for relocations in other sections as needed.
1482  // Record relocations for the debug_info and debug_line sections.
1483  DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1484  RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1485  if (!Map) {
1486  // Find debug_info and debug_types relocs by section rather than name
1487  // as there are multiple, comdat grouped, of these sections.
1488  if (RelSecName == "debug_info")
1489  Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
1490  .Relocs;
1491  else if (RelSecName == "debug_info.dwo")
1492  Map = &static_cast<DWARFSectionMap &>(
1493  InfoDWOSections[*RelocatedSection])
1494  .Relocs;
1495  else if (RelSecName == "debug_types")
1496  Map =
1497  &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1498  .Relocs;
1499  else if (RelSecName == "debug_types.dwo")
1500  Map = &static_cast<DWARFSectionMap &>(
1501  TypesDWOSections[*RelocatedSection])
1502  .Relocs;
1503  else
1504  continue;
1505  }
1506 
1507  if (Section.relocation_begin() == Section.relocation_end())
1508  continue;
1509 
1510  // Symbol to [address, section index] cache mapping.
1511  std::map<SymbolRef, SymInfo> AddrCache;
1512  bool (*Supports)(uint64_t);
1514  std::tie(Supports, Resolver) = getRelocationResolver(Obj);
1515  for (const RelocationRef &Reloc : Section.relocations()) {
1516  // FIXME: it's not clear how to correctly handle scattered
1517  // relocations.
1518  if (isRelocScattered(Obj, Reloc))
1519  continue;
1520 
1521  Expected<SymInfo> SymInfoOrErr =
1522  getSymbolInfo(Obj, Reloc, L, AddrCache);
1523  if (!SymInfoOrErr) {
1524  if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
1525  return;
1526  continue;
1527  }
1528 
1529  // Check if Resolver can handle this relocation type early so as not to
1530  // handle invalid cases in DWARFDataExtractor.
1531  //
1532  // TODO Don't store Resolver in every RelocAddrEntry.
1533  if (Supports && Supports(Reloc.getType())) {
1534  Map->try_emplace(Reloc.getOffset(),
1535  RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc,
1536  Resolver, SymInfoOrErr->Address});
1537  } else {
1539  Reloc.getTypeName(Type);
1540  ErrorPolicy EP = HandleError(
1541  createError("failed to compute relocation: " + Type + ", ",
1542  errorCodeToError(object_error::parse_failed)));
1543  if (EP == ErrorPolicy::Halt)
1544  return;
1545  }
1546  }
1547  }
1548 
1549  for (SectionName &S : SectionNames)
1550  if (SectionAmountMap[S.Name] > 1)
1551  S.IsNameUnique = false;
1552  }
1553 
1555  uint64_t Pos) const override {
1556  auto &Sec = static_cast<const DWARFSectionMap &>(S);
1557  RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1558  if (AI == Sec.Relocs.end())
1559  return None;
1560  return AI->second;
1561  }
1562 
1563  const object::ObjectFile *getFile() const override { return Obj; }
1564 
1565  ArrayRef<SectionName> getSectionNames() const override {
1566  return SectionNames;
1567  }
1568 
1569  bool isLittleEndian() const override { return IsLittleEndian; }
1570  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1571  const DWARFSection &getLineDWOSection() const override {
1572  return LineDWOSection;
1573  }
1574  const DWARFSection &getLocDWOSection() const override {
1575  return LocDWOSection;
1576  }
1577  StringRef getStringDWOSection() const override { return StringDWOSection; }
1578  const DWARFSection &getStringOffsetDWOSection() const override {
1579  return StringOffsetDWOSection;
1580  }
1581  const DWARFSection &getRangeDWOSection() const override {
1582  return RangeDWOSection;
1583  }
1584  const DWARFSection &getRnglistsDWOSection() const override {
1585  return RnglistsDWOSection;
1586  }
1587  const DWARFSection &getAddrSection() const override { return AddrSection; }
1588  StringRef getCUIndexSection() const override { return CUIndexSection; }
1589  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1590  StringRef getTUIndexSection() const override { return TUIndexSection; }
1591 
1592  // DWARF v5
1593  const DWARFSection &getStringOffsetSection() const override {
1594  return StringOffsetSection;
1595  }
1596  StringRef getLineStringSection() const override { return LineStringSection; }
1597 
1598  // Sections for DWARF5 split dwarf proposal.
1599  void forEachInfoDWOSections(
1600  function_ref<void(const DWARFSection &)> F) const override {
1601  for (auto &P : InfoDWOSections)
1602  F(P.second);
1603  }
1604  void forEachTypesDWOSections(
1605  function_ref<void(const DWARFSection &)> F) const override {
1606  for (auto &P : TypesDWOSections)
1607  F(P.second);
1608  }
1609 
1610  StringRef getAbbrevSection() const override { return AbbrevSection; }
1611  const DWARFSection &getLocSection() const override { return LocSection; }
1612  const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
1613  StringRef getARangeSection() const override { return ARangeSection; }
1614  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1615  StringRef getEHFrameSection() const override { return EHFrameSection; }
1616  const DWARFSection &getLineSection() const override { return LineSection; }
1617  StringRef getStringSection() const override { return StringSection; }
1618  const DWARFSection &getRangeSection() const override { return RangeSection; }
1619  const DWARFSection &getRnglistsSection() const override {
1620  return RnglistsSection;
1621  }
1622  StringRef getMacinfoSection() const override { return MacinfoSection; }
1623  const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
1624  const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
1625  const DWARFSection &getGnuPubNamesSection() const override {
1626  return GnuPubNamesSection;
1627  }
1628  const DWARFSection &getGnuPubTypesSection() const override {
1629  return GnuPubTypesSection;
1630  }
1631  const DWARFSection &getAppleNamesSection() const override {
1632  return AppleNamesSection;
1633  }
1634  const DWARFSection &getAppleTypesSection() const override {
1635  return AppleTypesSection;
1636  }
1637  const DWARFSection &getAppleNamespacesSection() const override {
1638  return AppleNamespacesSection;
1639  }
1640  const DWARFSection &getAppleObjCSection() const override {
1641  return AppleObjCSection;
1642  }
1643  const DWARFSection &getDebugNamesSection() const override {
1644  return DebugNamesSection;
1645  }
1646 
1647  StringRef getFileName() const override { return FileName; }
1648  uint8_t getAddressSize() const override { return AddressSize; }
1649  void forEachInfoSections(
1650  function_ref<void(const DWARFSection &)> F) const override {
1651  for (auto &P : InfoSections)
1652  F(P.second);
1653  }
1654  void forEachTypesSections(
1655  function_ref<void(const DWARFSection &)> F) const override {
1656  for (auto &P : TypesSections)
1657  F(P.second);
1658  }
1659 };
1660 } // namespace
1661 
1662 std::unique_ptr<DWARFContext>
1664  function_ref<ErrorPolicy(Error)> HandleError,
1665  std::string DWPName) {
1666  auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
1667  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
1668 }
1669 
1670 std::unique_ptr<DWARFContext>
1671 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1672  uint8_t AddrSize, bool isLittleEndian) {
1673  auto DObj =
1674  llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
1675  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
1676 }
1677 
1679  // Detect the architecture from the object file. We usually don't need OS
1680  // info to lookup a target and create register info.
1681  Triple TT;
1682  TT.setArch(Triple::ArchType(Obj.getArch()));
1685  std::string TargetLookupError;
1686  const Target *TheTarget =
1687  TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
1688  if (!TargetLookupError.empty())
1690  TargetLookupError.c_str());
1691  RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
1692  return Error::success();
1693 }
1694 
1696  // In theory, different compile units may have different address byte
1697  // sizes, but for simplicity we just use the address byte size of the
1698  // last compile unit. In practice the address size field is repeated across
1699  // various DWARF headers (at least in version 5) to make it easier to dump
1700  // them independently, not to enable varying the address size.
1701  uint8_t Addr = 0;
1702  for (const auto &CU : compile_units()) {
1703  Addr = CU->getAddressByteSize();
1704  break;
1705  }
1706  return Addr;
1707 }
1708 
1710  handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
1711  WithColor::warning() << Info.message() << '\n';
1712  });
1713 }
const DWARFUnitIndex & getTUIndex()
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: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)
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:253
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:1168
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:1172
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
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:613
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: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
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:238
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:341
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:48
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:315
bool isLittleEndian() const
Get the endianness for this extractor.
Definition: DataExtractor.h:56
const std::string & str() const
Definition: Triple.h:363
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: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: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: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: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: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: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: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...
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:381
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:985
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
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:841
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:223
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: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: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:124
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:480
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:1164
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