LLVM  17.0.0git
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/MapVector.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
41 #include "llvm/MC/TargetRegistry.h"
43 #include "llvm/Object/MachO.h"
44 #include "llvm/Object/ObjectFile.h"
46 #include "llvm/Support/Casting.h"
48 #include "llvm/Support/Error.h"
49 #include "llvm/Support/Format.h"
50 #include "llvm/Support/LEB128.h"
52 #include "llvm/Support/Path.h"
54 #include <algorithm>
55 #include <cstdint>
56 #include <deque>
57 #include <map>
58 #include <string>
59 #include <utility>
60 #include <vector>
61 
62 using namespace llvm;
63 using namespace dwarf;
64 using namespace object;
65 
66 #define DEBUG_TYPE "dwarf"
67 
71 
72 DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
73  std::string DWPName,
74  std::function<void(Error)> RecoverableErrorHandler,
75  std::function<void(Error)> WarningHandler)
76  : DIContext(CK_DWARF), DWPName(std::move(DWPName)),
77  RecoverableErrorHandler(RecoverableErrorHandler),
78  WarningHandler(WarningHandler), DObj(std::move(DObj)) {}
79 
80 DWARFContext::~DWARFContext() = default;
81 
82 /// Dump the UUID load command.
83 static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
84  auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
85  if (!MachO)
86  return;
87  for (auto LC : MachO->load_commands()) {
89  if (LC.C.cmd == MachO::LC_UUID) {
90  if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
91  OS << "error: UUID load command is too short.\n";
92  return;
93  }
94  OS << "UUID: ";
95  memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
96  OS.write_uuid(UUID);
97  Triple T = MachO->getArchTriple();
98  OS << " (" << T.getArchName() << ')';
99  OS << ' ' << MachO->getFileName() << '\n';
100  }
101  }
102 }
103 
105  std::vector<std::optional<StrOffsetsContributionDescriptor>>;
106 
107 // Collect all the contributions to the string offsets table from all units,
108 // sort them by their starting offsets and remove duplicates.
111  ContributionCollection Contributions;
112  for (const auto &U : Units)
113  if (const auto &C = U->getStringOffsetsTableContribution())
114  Contributions.push_back(C);
115  // Sort the contributions so that any invalid ones are placed at
116  // the start of the contributions vector. This way they are reported
117  // first.
118  llvm::sort(Contributions,
119  [](const std::optional<StrOffsetsContributionDescriptor> &L,
120  const std::optional<StrOffsetsContributionDescriptor> &R) {
121  if (L && R)
122  return L->Base < R->Base;
123  return R.has_value();
124  });
125 
126  // Uniquify contributions, as it is possible that units (specifically
127  // type units in dwo or dwp files) share contributions. We don't want
128  // to report them more than once.
129  Contributions.erase(
130  std::unique(Contributions.begin(), Contributions.end(),
131  [](const std::optional<StrOffsetsContributionDescriptor> &L,
132  const std::optional<StrOffsetsContributionDescriptor> &R) {
133  if (L && R)
134  return L->Base == R->Base && L->Size == R->Size;
135  return false;
136  }),
137  Contributions.end());
138  return Contributions;
139 }
140 
141 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
142 // string offsets section, where each compile or type unit contributes a
143 // number of entries (string offsets), with each contribution preceded by
144 // a header containing size and version number. Alternatively, it may be a
145 // monolithic series of string offsets, as generated by the pre-DWARF v5
146 // implementation of split DWARF; however, in that case we still need to
147 // collect contributions of units because the size of the offsets (4 or 8
148 // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
151  const DWARFObject &Obj,
152  const DWARFSection &StringOffsetsSection,
153  StringRef StringSection,
155  bool LittleEndian) {
156  auto Contributions = collectContributionData(Units);
157  DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
158  DataExtractor StrData(StringSection, LittleEndian, 0);
159  uint64_t SectionSize = StringOffsetsSection.Data.size();
160  uint64_t Offset = 0;
161  for (auto &Contribution : Contributions) {
162  // Report an ill-formed contribution.
163  if (!Contribution) {
164  OS << "error: invalid contribution to string offsets table in section ."
165  << SectionName << ".\n";
166  return;
167  }
168 
169  dwarf::DwarfFormat Format = Contribution->getFormat();
170  int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
171  uint16_t Version = Contribution->getVersion();
172  uint64_t ContributionHeader = Contribution->Base;
173  // In DWARF v5 there is a contribution header that immediately precedes
174  // the string offsets base (the location we have previously retrieved from
175  // the CU DIE's DW_AT_str_offsets attribute). The header is located either
176  // 8 or 16 bytes before the base, depending on the contribution's format.
177  if (Version >= 5)
178  ContributionHeader -= Format == DWARF32 ? 8 : 16;
179 
180  // Detect overlapping contributions.
181  if (Offset > ContributionHeader) {
184  "overlapping contributions to string offsets table in section .%s.",
185  SectionName.data()));
186  }
187  // Report a gap in the table.
188  if (Offset < ContributionHeader) {
189  OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
190  OS << (ContributionHeader - Offset) << "\n";
191  }
192  OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
193  // In DWARF v5 the contribution size in the descriptor does not equal
194  // the originally encoded length (it does not contain the length of the
195  // version field and the padding, a total of 4 bytes). Add them back in
196  // for reporting.
197  OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
198  << ", Format = " << dwarf::FormatString(Format)
199  << ", Version = " << Version << "\n";
200 
201  Offset = Contribution->Base;
202  unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
203  while (Offset - Contribution->Base < Contribution->Size) {
204  OS << format("0x%8.8" PRIx64 ": ", Offset);
205  uint64_t StringOffset =
206  StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
207  OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
208  const char *S = StrData.getCStr(&StringOffset);
209  if (S)
210  OS << format("\"%s\"", S);
211  OS << "\n";
212  }
213  }
214  // Report a gap at the end of the table.
215  if (Offset < SectionSize) {
216  OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
217  OS << (SectionSize - Offset) << "\n";
218  }
219 }
220 
221 // Dump the .debug_addr section.
222 static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
223  DIDumpOptions DumpOpts, uint16_t Version,
224  uint8_t AddrSize) {
225  uint64_t Offset = 0;
226  while (AddrData.isValidOffset(Offset)) {
227  DWARFDebugAddrTable AddrTable;
228  uint64_t TableOffset = Offset;
229  if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
230  DumpOpts.WarningHandler)) {
231  DumpOpts.RecoverableErrorHandler(std::move(Err));
232  // Keep going after an error, if we can, assuming that the length field
233  // could be read. If it couldn't, stop reading the section.
234  if (auto TableLength = AddrTable.getFullLength()) {
235  Offset = TableOffset + *TableLength;
236  continue;
237  }
238  break;
239  }
240  AddrTable.dump(OS, DumpOpts);
241  }
242 }
243 
244 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
246  raw_ostream &OS, DWARFDataExtractor &rnglistData,
247  llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)>
248  LookupPooledAddress,
249  DIDumpOptions DumpOpts) {
250  uint64_t Offset = 0;
251  while (rnglistData.isValidOffset(Offset)) {
253  uint64_t TableOffset = Offset;
254  if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
255  DumpOpts.RecoverableErrorHandler(std::move(Err));
256  uint64_t Length = Rnglists.length();
257  // Keep going after an error, if we can, assuming that the length field
258  // could be read. If it couldn't, stop reading the section.
259  if (Length == 0)
260  break;
261  Offset = TableOffset + Length;
262  } else {
263  Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
264  }
265  }
266 }
267 
268 std::unique_ptr<DWARFDebugMacro>
269 DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
270  auto Macro = std::make_unique<DWARFDebugMacro>();
271  auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
272  if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
273  ? compile_units()
274  : dwo_compile_units(),
275  SectionType == MacroSection
278  Data)
279  : Macro->parseMacinfo(Data)) {
280  RecoverableErrorHandler(std::move(Err));
281  Macro = nullptr;
282  }
283  };
284  switch (SectionType) {
285  case MacinfoSection: {
286  DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0);
287  ParseAndDump(Data, /*IsMacro=*/false);
288  break;
289  }
290  case MacinfoDwoSection: {
291  DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0);
292  ParseAndDump(Data, /*IsMacro=*/false);
293  break;
294  }
295  case MacroSection: {
296  DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(),
297  0);
298  ParseAndDump(Data, /*IsMacro=*/true);
299  break;
300  }
301  case MacroDwoSection: {
302  DWARFDataExtractor Data(DObj->getMacroDWOSection(), isLittleEndian(), 0);
303  ParseAndDump(Data, /*IsMacro=*/true);
304  break;
305  }
306  }
307  return Macro;
308 }
309 
311  DWARFDataExtractor Data, const DWARFObject &Obj,
312  std::optional<uint64_t> DumpOffset) {
313  uint64_t Offset = 0;
314 
315  while (Data.isValidOffset(Offset)) {
316  DWARFListTableHeader Header(".debug_loclists", "locations");
317  if (Error E = Header.extract(Data, &Offset)) {
319  return;
320  }
321 
322  Header.dump(Data, OS, DumpOpts);
323 
324  uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
325  Data.setAddressSize(Header.getAddrSize());
326  DWARFDebugLoclists Loc(Data, Header.getVersion());
327  if (DumpOffset) {
328  if (DumpOffset >= Offset && DumpOffset < EndOffset) {
329  Offset = *DumpOffset;
330  Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj,
331  nullptr, DumpOpts, /*Indent=*/0);
332  OS << "\n";
333  return;
334  }
335  } else {
336  Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);
337  }
338  Offset = EndOffset;
339  }
340 }
341 
343  DWARFDataExtractor Data, bool GnuStyle) {
344  DWARFDebugPubTable Table;
345  Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
346  Table.dump(OS);
347 }
348 
350  raw_ostream &OS, DIDumpOptions DumpOpts,
351  std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
352  uint64_t DumpType = DumpOpts.DumpType;
353 
354  StringRef Extension = sys::path::extension(DObj->getFileName());
355  bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
356 
357  // Print UUID header.
358  const auto *ObjFile = DObj->getFile();
359  if (DumpType & DIDT_UUID)
360  dumpUUID(OS, *ObjFile);
361 
362  // Print a header for each explicitly-requested section.
363  // Otherwise just print one for non-empty sections.
364  // Only print empty .dwo section headers when dumping a .dwo file.
365  bool Explicit = DumpType != DIDT_All && !IsDWO;
366  bool ExplicitDWO = Explicit && IsDWO;
367  auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
368  StringRef Section) -> std::optional<uint64_t> * {
369  unsigned Mask = 1U << ID;
370  bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
371  if (!Should)
372  return nullptr;
373  OS << "\n" << Name << " contents:\n";
374  return &DumpOffsets[ID];
375  };
376 
377  // Dump individual sections.
378  if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
379  DObj->getAbbrevSection()))
380  getDebugAbbrev()->dump(OS);
381  if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
382  DObj->getAbbrevDWOSection()))
383  getDebugAbbrevDWO()->dump(OS);
384 
385  auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
386  OS << '\n' << Name << " contents:\n";
387  if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
388  for (const auto &U : Units)
389  U->getDIEForOffset(*DumpOffset)
390  .dump(OS, 0, DumpOpts.noImplicitRecursion());
391  else
392  for (const auto &U : Units)
393  U->dump(OS, DumpOpts);
394  };
395  if ((DumpType & DIDT_DebugInfo)) {
396  if (Explicit || getNumCompileUnits())
397  dumpDebugInfo(".debug_info", info_section_units());
398  if (ExplicitDWO || getNumDWOCompileUnits())
399  dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
400  }
401 
402  auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
403  OS << '\n' << Name << " contents:\n";
404  for (const auto &U : Units)
405  if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
406  U->getDIEForOffset(*DumpOffset)
407  .dump(OS, 0, DumpOpts.noImplicitRecursion());
408  else
409  U->dump(OS, DumpOpts);
410  };
411  if ((DumpType & DIDT_DebugTypes)) {
412  if (Explicit || getNumTypeUnits())
413  dumpDebugType(".debug_types", types_section_units());
414  if (ExplicitDWO || getNumDWOTypeUnits())
415  dumpDebugType(".debug_types.dwo", dwo_types_section_units());
416  }
417 
418  DIDumpOptions LLDumpOpts = DumpOpts;
419  if (LLDumpOpts.Verbose)
420  LLDumpOpts.DisplayRawContents = true;
421 
422  if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
423  DObj->getLocSection().Data)) {
424  getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off);
425  }
426  if (const auto *Off =
427  shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
428  DObj->getLoclistsSection().Data)) {
429  DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
430  0);
431  dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
432  }
433  if (const auto *Off =
434  shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
435  DObj->getLoclistsDWOSection().Data)) {
436  DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
437  isLittleEndian(), 0);
438  dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
439  }
440 
441  if (const auto *Off =
442  shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
443  DObj->getLocDWOSection().Data)) {
444  DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
445  4);
446  DWARFDebugLoclists Loc(Data, /*Version=*/4);
447  if (*Off) {
448  uint64_t Offset = **Off;
449  Loc.dumpLocationList(&Offset, OS,
450  /*BaseAddr=*/std::nullopt, *DObj, nullptr,
451  LLDumpOpts,
452  /*Indent=*/0);
453  OS << "\n";
454  } else {
455  Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);
456  }
457  }
458 
459  if (const std::optional<uint64_t> *Off =
460  shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
461  DObj->getFrameSection().Data)) {
463  (*DF)->dump(OS, DumpOpts, *Off);
464  else
465  RecoverableErrorHandler(DF.takeError());
466  }
467 
468  if (const std::optional<uint64_t> *Off =
469  shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
470  DObj->getEHFrameSection().Data)) {
472  (*DF)->dump(OS, DumpOpts, *Off);
473  else
474  RecoverableErrorHandler(DF.takeError());
475  }
476 
477  if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
478  DObj->getMacroSection().Data)) {
479  if (auto Macro = getDebugMacro())
480  Macro->dump(OS);
481  }
482 
483  if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
484  DObj->getMacroDWOSection())) {
485  if (auto MacroDWO = getDebugMacroDWO())
486  MacroDWO->dump(OS);
487  }
488 
489  if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
490  DObj->getMacinfoSection())) {
491  if (auto Macinfo = getDebugMacinfo())
492  Macinfo->dump(OS);
493  }
494 
495  if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
496  DObj->getMacinfoDWOSection())) {
497  if (auto MacinfoDWO = getDebugMacinfoDWO())
498  MacinfoDWO->dump(OS);
499  }
500 
501  if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
502  DObj->getArangesSection())) {
503  uint64_t offset = 0;
504  DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
505  0);
507  while (arangesData.isValidOffset(offset)) {
508  if (Error E =
509  set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
510  RecoverableErrorHandler(std::move(E));
511  break;
512  }
513  set.dump(OS);
514  }
515  }
516 
517  auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
518  DIDumpOptions DumpOpts,
519  std::optional<uint64_t> DumpOffset) {
520  while (!Parser.done()) {
521  if (DumpOffset && Parser.getOffset() != *DumpOffset) {
522  Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
523  continue;
524  }
525  OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
526  << "]\n";
527  Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
528  DumpOpts.Verbose);
529  }
530  };
531 
532  auto DumpStrSection = [&](StringRef Section) {
533  DataExtractor StrData(Section, isLittleEndian(), 0);
534  uint64_t Offset = 0;
535  uint64_t StrOffset = 0;
536  while (StrData.isValidOffset(Offset)) {
537  Error Err = Error::success();
538  const char *CStr = StrData.getCStr(&Offset, &Err);
539  if (Err) {
540  DumpOpts.WarningHandler(std::move(Err));
541  return;
542  }
543  OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
544  OS.write_escaped(CStr);
545  OS << "\"\n";
546  StrOffset = Offset;
547  }
548  };
549 
550  if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
551  DObj->getLineSection().Data)) {
552  DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
553  0);
554  DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
555  DumpLineSection(Parser, DumpOpts, *Off);
556  }
557 
558  if (const auto *Off =
559  shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
560  DObj->getLineDWOSection().Data)) {
561  DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
562  isLittleEndian(), 0);
563  DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
564  DumpLineSection(Parser, DumpOpts, *Off);
565  }
566 
567  if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
568  DObj->getCUIndexSection())) {
569  getCUIndex().dump(OS);
570  }
571 
572  if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
573  DObj->getTUIndexSection())) {
574  getTUIndex().dump(OS);
575  }
576 
577  if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
578  DObj->getStrSection()))
579  DumpStrSection(DObj->getStrSection());
580 
581  if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
582  DObj->getStrDWOSection()))
583  DumpStrSection(DObj->getStrDWOSection());
584 
585  if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
586  DObj->getLineStrSection()))
587  DumpStrSection(DObj->getLineStrSection());
588 
589  if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
590  DObj->getAddrSection().Data)) {
591  DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
592  isLittleEndian(), 0);
593  dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
594  }
595 
596  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
597  DObj->getRangesSection().Data)) {
598  uint8_t savedAddressByteSize = getCUAddrSize();
599  DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
600  isLittleEndian(), savedAddressByteSize);
601  uint64_t offset = 0;
602  DWARFDebugRangeList rangeList;
603  while (rangesData.isValidOffset(offset)) {
604  if (Error E = rangeList.extract(rangesData, &offset)) {
605  DumpOpts.RecoverableErrorHandler(std::move(E));
606  break;
607  }
608  rangeList.dump(OS);
609  }
610  }
611 
612  auto LookupPooledAddress =
613  [&](uint32_t Index) -> std::optional<SectionedAddress> {
614  const auto &CUs = compile_units();
615  auto I = CUs.begin();
616  if (I == CUs.end())
617  return std::nullopt;
618  return (*I)->getAddrOffsetSectionItem(Index);
619  };
620 
621  if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
622  DObj->getRnglistsSection().Data)) {
623  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
624  isLittleEndian(), 0);
625  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
626  }
627 
628  if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
629  DObj->getRnglistsDWOSection().Data)) {
630  DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
631  isLittleEndian(), 0);
632  dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
633  }
634 
635  if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
636  DObj->getPubnamesSection().Data)) {
637  DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
638  isLittleEndian(), 0);
639  dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
640  }
641 
642  if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
643  DObj->getPubtypesSection().Data)) {
644  DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
645  isLittleEndian(), 0);
646  dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
647  }
648 
649  if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
650  DObj->getGnuPubnamesSection().Data)) {
651  DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
652  isLittleEndian(), 0);
653  dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
654  }
655 
656  if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
657  DObj->getGnuPubtypesSection().Data)) {
658  DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
659  isLittleEndian(), 0);
660  dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
661  }
662 
663  if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
664  DObj->getStrOffsetsSection().Data))
666  OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
667  DObj->getStrSection(), normal_units(), isLittleEndian());
668  if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
669  DObj->getStrOffsetsDWOSection().Data))
670  dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
671  DObj->getStrOffsetsDWOSection(),
672  DObj->getStrDWOSection(), dwo_units(),
673  isLittleEndian());
674 
675  if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
676  DObj->getGdbIndexSection())) {
677  getGdbIndex().dump(OS);
678  }
679 
680  if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
681  DObj->getAppleNamesSection().Data))
682  getAppleNames().dump(OS);
683 
684  if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
685  DObj->getAppleTypesSection().Data))
686  getAppleTypes().dump(OS);
687 
688  if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
689  DObj->getAppleNamespacesSection().Data))
690  getAppleNamespaces().dump(OS);
691 
692  if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
693  DObj->getAppleObjCSection().Data))
694  getAppleObjC().dump(OS);
695  if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
696  DObj->getNamesSection().Data))
697  getDebugNames().dump(OS);
698 }
699 
701  bool IsDWO) {
702  parseDWOUnits(LazyParse);
703 
704  if (const auto &TUI = getTUIndex()) {
705  if (const auto *R = TUI.getFromHash(Hash))
706  return dyn_cast_or_null<DWARFTypeUnit>(
707  DWOUnits.getUnitForIndexEntry(*R));
708  return nullptr;
709  }
710 
711  struct UnitContainers {
712  const DWARFUnitVector &Units;
713  std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> &Map;
714  };
715  UnitContainers Units = IsDWO ? UnitContainers{DWOUnits, DWOTypeUnits}
716  : UnitContainers{NormalUnits, NormalTypeUnits};
717  if (!Units.Map) {
718  Units.Map.emplace();
719  for (const auto &U : IsDWO ? dwo_units() : normal_units()) {
720  if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
721  (*Units.Map)[TU->getTypeHash()] = TU;
722  }
723  }
724 
725  return (*Units.Map)[Hash];
726 }
727 
729  parseDWOUnits(LazyParse);
730 
731  if (const auto &CUI = getCUIndex()) {
732  if (const auto *R = CUI.getFromHash(Hash))
733  return dyn_cast_or_null<DWARFCompileUnit>(
734  DWOUnits.getUnitForIndexEntry(*R));
735  return nullptr;
736  }
737 
738  // If there's no index, just search through the CUs in the DWO - there's
739  // probably only one unless this is something like LTO - though an in-process
740  // built/cached lookup table could be used in that case to improve repeated
741  // lookups of different CUs in the DWO.
742  for (const auto &DWOCU : dwo_compile_units()) {
743  // Might not have parsed DWO ID yet.
744  if (!DWOCU->getDWOId()) {
745  if (std::optional<uint64_t> DWOId =
746  toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
747  DWOCU->setDWOId(*DWOId);
748  else
749  // No DWO ID?
750  continue;
751  }
752  if (DWOCU->getDWOId() == Hash)
753  return dyn_cast<DWARFCompileUnit>(DWOCU.get());
754  }
755  return nullptr;
756 }
757 
759  parseNormalUnits();
760  if (auto *CU = NormalUnits.getUnitForOffset(Offset))
761  return CU->getDIEForOffset(Offset);
762  return DWARFDie();
763 }
764 
766  bool Success = true;
767  DWARFVerifier verifier(OS, *this, DumpOpts);
768 
769  Success &= verifier.handleDebugAbbrev();
770  if (DumpOpts.DumpType & DIDT_DebugCUIndex)
771  Success &= verifier.handleDebugCUIndex();
772  if (DumpOpts.DumpType & DIDT_DebugTUIndex)
773  Success &= verifier.handleDebugTUIndex();
774  if (DumpOpts.DumpType & DIDT_DebugInfo)
775  Success &= verifier.handleDebugInfo();
776  if (DumpOpts.DumpType & DIDT_DebugLine)
777  Success &= verifier.handleDebugLine();
778  Success &= verifier.handleAccelTables();
779  return Success;
780 }
781 
785  using EntryMap = DenseMap<uint32_t, EntryType>;
786  EntryMap Map;
787  if (DObj.getCUIndexSection().empty())
788  return;
789 
790  uint64_t Offset = 0;
791  uint32_t TruncOffset = 0;
792  DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
793  if (!(C.getParseCUTUIndexManually() ||
794  S.Data.size() >= std::numeric_limits<uint32_t>::max()))
795  return;
796 
797  DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
798  while (Data.isValidOffset(Offset)) {
799  DWARFUnitHeader Header;
800  if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
801  logAllUnhandledErrors(
802  createError("Failed to parse CU header in DWP file"), errs());
803  Map.clear();
804  break;
805  }
806 
807  auto Iter = Map.insert({TruncOffset,
808  {Header.getOffset(), Header.getNextUnitOffset() -
809  Header.getOffset()}});
810  if (!Iter.second) {
811  logAllUnhandledErrors(
812  createError("Collision occured between for truncated offset 0x" +
813  Twine::utohexstr(TruncOffset)),
814  errs());
815  Map.clear();
816  return;
817  }
818 
819  Offset = Header.getNextUnitOffset();
820  TruncOffset = Offset;
821  }
822  });
823 
824  if (Map.empty())
825  return;
826 
827  for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
828  if (!E.isValid())
829  continue;
830  DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
831  auto Iter = Map.find(CUOff.getOffset());
832  if (Iter == Map.end()) {
833  logAllUnhandledErrors(createError("Could not find CU offset 0x" +
834  Twine::utohexstr(CUOff.getOffset()) +
835  " in the Map"),
836  errs());
837  break;
838  }
839  CUOff.setOffset(Iter->second.getOffset());
840  if (CUOff.getOffset() != Iter->second.getOffset())
841  logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
842  "match calculated length at offset 0x" +
843  Twine::utohexstr(CUOff.getOffset())),
844  errs());
845  }
846 
847  return;
848 }
849 
850 const DWARFUnitIndex &DWARFContext::getCUIndex() {
851  if (CUIndex)
852  return *CUIndex;
853 
854  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
855  CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
856  CUIndex->parse(CUIndexData);
857  fixupIndex(*DObj, *this, *CUIndex.get());
858  return *CUIndex;
859 }
860 
862  if (TUIndex)
863  return *TUIndex;
864 
865  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
866  TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
867  bool isParseSuccessful = TUIndex->parse(TUIndexData);
868  // If we are parsing TU-index and for .debug_types section we don't need
869  // to do anything.
870  if (isParseSuccessful && TUIndex->getVersion() != 2)
871  fixupIndex(*DObj, *this, *TUIndex.get());
872  return *TUIndex;
873 }
874 
876  if (GdbIndex)
877  return *GdbIndex;
878 
879  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
880  GdbIndex = std::make_unique<DWARFGdbIndex>();
881  GdbIndex->parse(GdbIndexData);
882  return *GdbIndex;
883 }
884 
886  if (Abbrev)
887  return Abbrev.get();
888 
889  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
890 
891  Abbrev.reset(new DWARFDebugAbbrev());
892  Abbrev->extract(abbrData);
893  return Abbrev.get();
894 }
895 
897  if (AbbrevDWO)
898  return AbbrevDWO.get();
899 
900  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
901  AbbrevDWO.reset(new DWARFDebugAbbrev());
902  AbbrevDWO->extract(abbrData);
903  return AbbrevDWO.get();
904 }
905 
907  if (Loc)
908  return Loc.get();
909 
910  // Assume all units have the same address byte size.
911  auto LocData =
913  ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(),
914  getUnitAtIndex(0)->getAddressByteSize())
916  Loc.reset(new DWARFDebugLoc(std::move(LocData)));
917  return Loc.get();
918 }
919 
921  if (Aranges)
922  return Aranges.get();
923 
924  Aranges.reset(new DWARFDebugAranges());
925  Aranges->generate(this);
926  return Aranges.get();
927 }
928 
930  if (DebugFrame)
931  return DebugFrame.get();
932 
933  const DWARFSection &DS = DObj->getFrameSection();
934 
935  // There's a "bug" in the DWARFv3 standard with respect to the target address
936  // size within debug frame sections. While DWARF is supposed to be independent
937  // of its container, FDEs have fields with size being "target address size",
938  // which isn't specified in DWARF in general. It's only specified for CUs, but
939  // .eh_frame can appear without a .debug_info section. Follow the example of
940  // other tools (libdwarf) and extract this from the container (ObjectFile
941  // provides this information). This problem is fixed in DWARFv4
942  // See this dwarf-discuss discussion for more details:
943  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
944  DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
945  DObj->getAddressSize());
946  auto DF =
947  std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false, DS.Address);
948  if (Error E = DF->parse(DebugFrameData))
949  return std::move(E);
950 
951  DebugFrame.swap(DF);
952  return DebugFrame.get();
953 }
954 
956  if (EHFrame)
957  return EHFrame.get();
958 
959  const DWARFSection &DS = DObj->getEHFrameSection();
960  DWARFDataExtractor DebugFrameData(*DObj, DS, isLittleEndian(),
961  DObj->getAddressSize());
962 
963  auto DF =
964  std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true, DS.Address);
965  if (Error E = DF->parse(DebugFrameData))
966  return std::move(E);
967  DebugFrame.swap(DF);
968  return DebugFrame.get();
969 }
970 
972  if (!Macro)
973  Macro = parseMacroOrMacinfo(MacroSection);
974  return Macro.get();
975 }
976 
978  if (!MacroDWO)
979  MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
980  return MacroDWO.get();
981 }
982 
984  if (!Macinfo)
985  Macinfo = parseMacroOrMacinfo(MacinfoSection);
986  return Macinfo.get();
987 }
988 
990  if (!MacinfoDWO)
991  MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
992  return MacinfoDWO.get();
993 }
994 
995 template <typename T>
996 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
997  const DWARFSection &Section, StringRef StringSection,
998  bool IsLittleEndian) {
999  if (Cache)
1000  return *Cache;
1001  DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
1002  DataExtractor StrData(StringSection, IsLittleEndian, 0);
1003  Cache.reset(new T(AccelSection, StrData));
1004  if (Error E = Cache->extract())
1006  return *Cache;
1007 }
1008 
1010  return getAccelTable(Names, *DObj, DObj->getNamesSection(),
1011  DObj->getStrSection(), isLittleEndian());
1012 }
1013 
1015  return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
1016  DObj->getStrSection(), isLittleEndian());
1017 }
1018 
1020  return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
1021  DObj->getStrSection(), isLittleEndian());
1022 }
1023 
1025  return getAccelTable(AppleNamespaces, *DObj,
1026  DObj->getAppleNamespacesSection(),
1027  DObj->getStrSection(), isLittleEndian());
1028 }
1029 
1031  return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
1032  DObj->getStrSection(), isLittleEndian());
1033 }
1034 
1038  getLineTableForUnit(U, WarningHandler);
1039  if (!ExpectedLineTable) {
1040  WarningHandler(ExpectedLineTable.takeError());
1041  return nullptr;
1042  }
1043  return *ExpectedLineTable;
1044 }
1045 
1047  DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
1048  if (!Line)
1049  Line.reset(new DWARFDebugLine);
1050 
1051  auto UnitDIE = U->getUnitDIE();
1052  if (!UnitDIE)
1053  return nullptr;
1054 
1055  auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
1056  if (!Offset)
1057  return nullptr; // No line table for this compile unit.
1058 
1059  uint64_t stmtOffset = *Offset + U->getLineTableOffset();
1060  // See if the line table is cached.
1061  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
1062  return lt;
1063 
1064  // Make sure the offset is good before we try to parse.
1065  if (stmtOffset >= U->getLineSection().Data.size())
1066  return nullptr;
1067 
1068  // We have to parse it first.
1069  DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
1070  U->getAddressByteSize());
1071  return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
1072  RecoverableErrorHandler);
1073 }
1074 
1076  if (!Line)
1077  return;
1078 
1079  auto UnitDIE = U->getUnitDIE();
1080  if (!UnitDIE)
1081  return;
1082 
1083  auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
1084  if (!Offset)
1085  return;
1086 
1087  uint64_t stmtOffset = *Offset + U->getLineTableOffset();
1088  Line->clearLineTable(stmtOffset);
1089 }
1090 
1091 void DWARFContext::parseNormalUnits() {
1092  if (!NormalUnits.empty())
1093  return;
1094  DObj->forEachInfoSections([&](const DWARFSection &S) {
1095  NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
1096  });
1097  NormalUnits.finishedInfoUnits();
1098  DObj->forEachTypesSections([&](const DWARFSection &S) {
1099  NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES);
1100  });
1101 }
1102 
1103 void DWARFContext::parseDWOUnits(bool Lazy) {
1104  if (!DWOUnits.empty())
1105  return;
1106  DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
1107  DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
1108  });
1109  DWOUnits.finishedInfoUnits();
1110  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
1111  DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy);
1112  });
1113 }
1114 
1116  parseNormalUnits();
1117  return dyn_cast_or_null<DWARFCompileUnit>(
1118  NormalUnits.getUnitForOffset(Offset));
1119 }
1120 
1122  // First, get the offset of the compile unit.
1123  uint64_t CUOffset = getDebugAranges()->findAddress(Address);
1124  // Retrieve the compile unit.
1125  if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
1126  return OffsetCU;
1127 
1128  // Global variables are often not found by the above search, for one of two
1129  // reasons:
1130  // 1. .debug_aranges may not include global variables. On clang, it seems we
1131  // put the globals in the aranges, but this isn't true for gcc.
1132  // 2. Even if the global variable is in a .debug_arange, global variables
1133  // may not be captured in the [start, end) addresses described by the
1134  // parent compile unit.
1135  //
1136  // So, we walk the CU's and their child DI's manually, looking for the
1137  // specific global variable.
1138  for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
1139  if (DWARFDie Die = CU->getVariableForAddress(Address)) {
1140  return static_cast<DWARFCompileUnit *>(CU.get());
1141  }
1142  }
1143  return nullptr;
1144 }
1145 
1147  DIEsForAddress Result;
1148 
1150  if (!CU)
1151  return Result;
1152 
1153  Result.CompileUnit = CU;
1154  Result.FunctionDIE = CU->getSubroutineForAddress(Address);
1155 
1156  std::vector<DWARFDie> Worklist;
1157  Worklist.push_back(Result.FunctionDIE);
1158  while (!Worklist.empty()) {
1159  DWARFDie DIE = Worklist.back();
1160  Worklist.pop_back();
1161 
1162  if (!DIE.isValid())
1163  continue;
1164 
1165  if (DIE.getTag() == DW_TAG_lexical_block &&
1166  DIE.addressRangeContainsAddress(Address)) {
1167  Result.BlockDIE = DIE;
1168  break;
1169  }
1170 
1171  append_range(Worklist, DIE);
1172  }
1173 
1174  return Result;
1175 }
1176 
1177 /// TODO: change input parameter from "uint64_t Address"
1178 /// into "SectionedAddress Address"
1180  DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind,
1182  std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,
1183  std::optional<uint64_t> &StartAddress) {
1184  // The address may correspond to instruction in some inlined function,
1185  // so we have to build the chain of inlined functions and take the
1186  // name of the topmost function in it.
1187  SmallVector<DWARFDie, 4> InlinedChain;
1188  CU->getInlinedChainForAddress(Address, InlinedChain);
1189  if (InlinedChain.empty())
1190  return false;
1191 
1192  const DWARFDie &DIE = InlinedChain[0];
1193  bool FoundResult = false;
1194  const char *Name = nullptr;
1195  if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
1196  FunctionName = Name;
1197  FoundResult = true;
1198  }
1199  std::string DeclFile = DIE.getDeclFile(FileNameKind);
1200  if (!DeclFile.empty()) {
1201  StartFile = DeclFile;
1202  FoundResult = true;
1203  }
1204  if (auto DeclLineResult = DIE.getDeclLine()) {
1205  StartLine = DeclLineResult;
1206  FoundResult = true;
1207  }
1208  if (auto LowPcAddr = toSectionedAddress(DIE.find(DW_AT_low_pc)))
1209  StartAddress = LowPcAddr->Address;
1210  return FoundResult;
1211 }
1212 
1213 static std::optional<int64_t>
1215  std::optional<unsigned> FrameBaseReg) {
1216  if (!Expr.empty() &&
1217  (Expr[0] == DW_OP_fbreg ||
1218  (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1219  unsigned Count;
1220  int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
1221  // A single DW_OP_fbreg or DW_OP_breg.
1222  if (Expr.size() == Count + 1)
1223  return Offset;
1224  // Same + DW_OP_deref (Fortran arrays look like this).
1225  if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1226  return Offset;
1227  // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1228  }
1229  return std::nullopt;
1230 }
1231 
1232 void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
1233  DWARFDie Die, std::vector<DILocal> &Result) {
1234  if (Die.getTag() == DW_TAG_variable ||
1235  Die.getTag() == DW_TAG_formal_parameter) {
1236  DILocal Local;
1237  if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
1238  Local.FunctionName = Name;
1239 
1240  std::optional<unsigned> FrameBaseReg;
1241  if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
1242  if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
1243  if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1244  (*Expr)[0] <= DW_OP_reg31) {
1245  FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1246  }
1247 
1248  if (Expected<std::vector<DWARFLocationExpression>> Loc =
1249  Die.getLocations(DW_AT_location)) {
1250  for (const auto &Entry : *Loc) {
1251  if (std::optional<int64_t> FrameOffset =
1252  getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
1253  Local.FrameOffset = *FrameOffset;
1254  break;
1255  }
1256  }
1257  } else {
1258  // FIXME: missing DW_AT_location is OK here, but other errors should be
1259  // reported to the user.
1260  consumeError(Loc.takeError());
1261  }
1262 
1263  if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
1264  Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
1265 
1266  if (auto Origin =
1267  Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1268  Die = Origin;
1269  if (auto NameAttr = Die.find(DW_AT_name))
1270  if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
1271  Local.Name = *Name;
1272  if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
1273  Local.Size = Type.getTypeSize(getCUAddrSize());
1274  if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
1275  if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
1276  LT->getFileNameByIndex(
1277  *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),
1279  Local.DeclFile);
1280  }
1281  if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
1282  Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
1283 
1284  Result.push_back(Local);
1285  return;
1286  }
1287 
1288  if (Die.getTag() == DW_TAG_inlined_subroutine)
1289  if (auto Origin =
1290  Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
1291  Subprogram = Origin;
1292 
1293  for (auto Child : Die)
1294  addLocalsForDie(CU, Subprogram, Child, Result);
1295 }
1296 
1297 std::vector<DILocal>
1299  std::vector<DILocal> Result;
1300  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1301  if (!CU)
1302  return Result;
1303 
1304  DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
1305  if (Subprogram.isValid())
1306  addLocalsForDie(CU, Subprogram, Subprogram, Result);
1307  return Result;
1308 }
1309 
1312  DILineInfo Result;
1313  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1314  if (!CU)
1315  return Result;
1316 
1318  CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
1319  Result.StartFileName, Result.StartLine, Result.StartAddress);
1320  if (Spec.FLIKind != FileLineInfoKind::None) {
1321  if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
1322  LineTable->getFileLineInfoForAddress(
1323  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1324  Spec.FLIKind, Result);
1325  }
1326  }
1327 
1328  return Result;
1329 }
1330 
1331 DILineInfo
1333  DILineInfo Result;
1334  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1335  if (!CU)
1336  return Result;
1337 
1338  if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
1339  Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
1340  Result.Line = Die.getDeclLine();
1341  }
1342 
1343  return Result;
1344 }
1345 
1348  DILineInfoTable Lines;
1349  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1350  if (!CU)
1351  return Lines;
1352 
1353  uint32_t StartLine = 0;
1354  std::string StartFileName;
1355  std::string FunctionName(DILineInfo::BadString);
1356  std::optional<uint64_t> StartAddress;
1357  getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
1358  Spec.FLIKind, FunctionName,
1359  StartFileName, StartLine, StartAddress);
1360 
1361  // If the Specifier says we don't need FileLineInfo, just
1362  // return the top-most function at the starting address.
1363  if (Spec.FLIKind == FileLineInfoKind::None) {
1364  DILineInfo Result;
1365  Result.FunctionName = FunctionName;
1366  Result.StartFileName = StartFileName;
1367  Result.StartLine = StartLine;
1368  Result.StartAddress = StartAddress;
1369  Lines.push_back(std::make_pair(Address.Address, Result));
1370  return Lines;
1371  }
1372 
1373  const DWARFLineTable *LineTable = getLineTableForUnit(CU);
1374 
1375  // Get the index of row we're looking for in the line table.
1376  std::vector<uint32_t> RowVector;
1377  if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1378  Size, RowVector)) {
1379  return Lines;
1380  }
1381 
1382  for (uint32_t RowIndex : RowVector) {
1383  // Take file number and line/column from the row.
1384  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
1385  DILineInfo Result;
1386  LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
1387  Spec.FLIKind, Result.FileName);
1388  Result.FunctionName = FunctionName;
1389  Result.Line = Row.Line;
1390  Result.Column = Row.Column;
1391  Result.StartFileName = StartFileName;
1392  Result.StartLine = StartLine;
1393  Result.StartAddress = StartAddress;
1394  Lines.push_back(std::make_pair(Row.Address.Address, Result));
1395  }
1396 
1397  return Lines;
1398 }
1399 
1403  DIInliningInfo InliningInfo;
1404 
1405  DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
1406  if (!CU)
1407  return InliningInfo;
1408 
1409  const DWARFLineTable *LineTable = nullptr;
1410  SmallVector<DWARFDie, 4> InlinedChain;
1411  CU->getInlinedChainForAddress(Address.Address, InlinedChain);
1412  if (InlinedChain.size() == 0) {
1413  // If there is no DIE for address (e.g. it is in unavailable .dwo file),
1414  // try to at least get file/line info from symbol table.
1415  if (Spec.FLIKind != FileLineInfoKind::None) {
1416  DILineInfo Frame;
1417  LineTable = getLineTableForUnit(CU);
1418  if (LineTable && LineTable->getFileLineInfoForAddress(
1419  {Address.Address, Address.SectionIndex},
1420  CU->getCompilationDir(), Spec.FLIKind, Frame))
1421  InliningInfo.addFrame(Frame);
1422  }
1423  return InliningInfo;
1424  }
1425 
1426  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
1427  for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
1428  DWARFDie &FunctionDIE = InlinedChain[i];
1429  DILineInfo Frame;
1430  // Get function name if necessary.
1431  if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
1432  Frame.FunctionName = Name;
1433  if (auto DeclLineResult = FunctionDIE.getDeclLine())
1434  Frame.StartLine = DeclLineResult;
1435  Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
1436  if (auto LowPcAddr = toSectionedAddress(FunctionDIE.find(DW_AT_low_pc)))
1437  Frame.StartAddress = LowPcAddr->Address;
1438  if (Spec.FLIKind != FileLineInfoKind::None) {
1439  if (i == 0) {
1440  // For the topmost frame, initialize the line table of this
1441  // compile unit and fetch file/line info from it.
1442  LineTable = getLineTableForUnit(CU);
1443  // For the topmost routine, get file/line info from line table.
1444  if (LineTable)
1445  LineTable->getFileLineInfoForAddress(
1446  {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1447  Spec.FLIKind, Frame);
1448  } else {
1449  // Otherwise, use call file, call line and call column from
1450  // previous DIE in inlined chain.
1451  if (LineTable)
1452  LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
1453  Spec.FLIKind, Frame.FileName);
1454  Frame.Line = CallLine;
1455  Frame.Column = CallColumn;
1456  Frame.Discriminator = CallDiscriminator;
1457  }
1458  // Get call file/line/column of a current DIE.
1459  if (i + 1 < n) {
1460  FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
1461  CallDiscriminator);
1462  }
1463  }
1464  InliningInfo.addFrame(Frame);
1465  }
1466  return InliningInfo;
1467 }
1468 
1469 std::shared_ptr<DWARFContext>
1471  if (auto S = DWP.lock()) {
1472  DWARFContext *Ctxt = S->Context.get();
1473  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1474  }
1475 
1476  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
1477 
1478  if (auto S = Entry->lock()) {
1479  DWARFContext *Ctxt = S->Context.get();
1480  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1481  }
1482 
1484  if (!CheckedForDWP) {
1485  SmallString<128> DWPName;
1487  this->DWPName.empty()
1488  ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
1489  : StringRef(this->DWPName));
1490  if (Obj) {
1491  Entry = &DWP;
1492  return Obj;
1493  } else {
1494  CheckedForDWP = true;
1495  // TODO: Should this error be handled (maybe in a high verbosity mode)
1496  // before falling back to .dwo files?
1497  consumeError(Obj.takeError());
1498  }
1499  }
1500 
1501  return object::ObjectFile::createObjectFile(AbsolutePath);
1502  }();
1503 
1504  if (!Obj) {
1505  // TODO: Actually report errors helpfully.
1506  consumeError(Obj.takeError());
1507  return nullptr;
1508  }
1509 
1510  auto S = std::make_shared<DWOFile>();
1511  S->File = std::move(Obj.get());
1512  S->Context = DWARFContext::create(*S->File.getBinary(),
1514  *Entry = S;
1515  auto *Ctxt = S->Context.get();
1516  return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
1517 }
1518 
1519 static Error createError(const Twine &Reason, llvm::Error E) {
1520  return make_error<StringError>(Reason + toString(std::move(E)),
1522 }
1523 
1524 /// SymInfo contains information about symbol: it's address
1525 /// and section index which is -1LL for absolute symbols.
1526 struct SymInfo {
1529 };
1530 
1531 /// Returns the address of symbol relocation used against and a section index.
1532 /// Used for futher relocations computation. Symbol's section load address is
1534  const RelocationRef &Reloc,
1535  const LoadedObjectInfo *L,
1536  std::map<SymbolRef, SymInfo> &Cache) {
1537  SymInfo Ret = {0, (uint64_t)-1LL};
1539  object::symbol_iterator Sym = Reloc.getSymbol();
1540 
1541  std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
1542  // First calculate the address of the symbol or section as it appears
1543  // in the object file
1544  if (Sym != Obj.symbol_end()) {
1545  bool New;
1546  std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
1547  if (!New)
1548  return CacheIt->second;
1549 
1550  Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
1551  if (!SymAddrOrErr)
1552  return createError("failed to compute symbol address: ",
1553  SymAddrOrErr.takeError());
1554 
1555  // Also remember what section this symbol is in for later
1556  auto SectOrErr = Sym->getSection();
1557  if (!SectOrErr)
1558  return createError("failed to get symbol section: ",
1559  SectOrErr.takeError());
1560 
1561  RSec = *SectOrErr;
1562  Ret.Address = *SymAddrOrErr;
1563  } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1564  RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1565  Ret.Address = RSec->getAddress();
1566  }
1567 
1568  if (RSec != Obj.section_end())
1569  Ret.SectionIndex = RSec->getIndex();
1570 
1571  // If we are given load addresses for the sections, we need to adjust:
1572  // SymAddr = (Address of Symbol Or Section in File) -
1573  // (Address of Section in File) +
1574  // (Load Address of Section)
1575  // RSec is now either the section being targeted or the section
1576  // containing the symbol being targeted. In either case,
1577  // we need to perform the same computation.
1578  if (L && RSec != Obj.section_end())
1579  if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1580  Ret.Address += SectionLoadAddress - RSec->getAddress();
1581 
1582  if (CacheIt != Cache.end())
1583  CacheIt->second = Ret;
1584 
1585  return Ret;
1586 }
1587 
1588 static bool isRelocScattered(const object::ObjectFile &Obj,
1589  const RelocationRef &Reloc) {
1590  const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1591  if (!MachObj)
1592  return false;
1593  // MachO also has relocations that point to sections and
1594  // scattered relocations.
1595  auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1596  return MachObj->isRelocationScattered(RelocInfo);
1597 }
1598 
1599 namespace {
1600 struct DWARFSectionMap final : public DWARFSection {
1601  RelocAddrMap Relocs;
1602 };
1603 
1604 class DWARFObjInMemory final : public DWARFObject {
1605  bool IsLittleEndian;
1606  uint8_t AddressSize;
1607  StringRef FileName;
1608  const object::ObjectFile *Obj = nullptr;
1609  std::vector<SectionName> SectionNames;
1610 
1611  using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
1612  std::map<object::SectionRef, unsigned>>;
1613 
1614  InfoSectionMap InfoSections;
1615  InfoSectionMap TypesSections;
1616  InfoSectionMap InfoDWOSections;
1617  InfoSectionMap TypesDWOSections;
1618 
1619  DWARFSectionMap LocSection;
1620  DWARFSectionMap LoclistsSection;
1621  DWARFSectionMap LoclistsDWOSection;
1622  DWARFSectionMap LineSection;
1623  DWARFSectionMap RangesSection;
1624  DWARFSectionMap RnglistsSection;
1625  DWARFSectionMap StrOffsetsSection;
1626  DWARFSectionMap LineDWOSection;
1627  DWARFSectionMap FrameSection;
1628  DWARFSectionMap EHFrameSection;
1629  DWARFSectionMap LocDWOSection;
1630  DWARFSectionMap StrOffsetsDWOSection;
1631  DWARFSectionMap RangesDWOSection;
1632  DWARFSectionMap RnglistsDWOSection;
1633  DWARFSectionMap AddrSection;
1634  DWARFSectionMap AppleNamesSection;
1635  DWARFSectionMap AppleTypesSection;
1636  DWARFSectionMap AppleNamespacesSection;
1637  DWARFSectionMap AppleObjCSection;
1638  DWARFSectionMap NamesSection;
1639  DWARFSectionMap PubnamesSection;
1640  DWARFSectionMap PubtypesSection;
1641  DWARFSectionMap GnuPubnamesSection;
1642  DWARFSectionMap GnuPubtypesSection;
1643  DWARFSectionMap MacroSection;
1644 
1645  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
1646  return StringSwitch<DWARFSectionMap *>(Name)
1647  .Case("debug_loc", &LocSection)
1648  .Case("debug_loclists", &LoclistsSection)
1649  .Case("debug_loclists.dwo", &LoclistsDWOSection)
1650  .Case("debug_line", &LineSection)
1651  .Case("debug_frame", &FrameSection)
1652  .Case("eh_frame", &EHFrameSection)
1653  .Case("debug_str_offsets", &StrOffsetsSection)
1654  .Case("debug_ranges", &RangesSection)
1655  .Case("debug_rnglists", &RnglistsSection)
1656  .Case("debug_loc.dwo", &LocDWOSection)
1657  .Case("debug_line.dwo", &LineDWOSection)
1658  .Case("debug_names", &NamesSection)
1659  .Case("debug_rnglists.dwo", &RnglistsDWOSection)
1660  .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
1661  .Case("debug_addr", &AddrSection)
1662  .Case("apple_names", &AppleNamesSection)
1663  .Case("debug_pubnames", &PubnamesSection)
1664  .Case("debug_pubtypes", &PubtypesSection)
1665  .Case("debug_gnu_pubnames", &GnuPubnamesSection)
1666  .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
1667  .Case("apple_types", &AppleTypesSection)
1668  .Case("apple_namespaces", &AppleNamespacesSection)
1669  .Case("apple_namespac", &AppleNamespacesSection)
1670  .Case("apple_objc", &AppleObjCSection)
1671  .Case("debug_macro", &MacroSection)
1672  .Default(nullptr);
1673  }
1674 
1675  StringRef AbbrevSection;
1676  StringRef ArangesSection;
1677  StringRef StrSection;
1678  StringRef MacinfoSection;
1679  StringRef MacinfoDWOSection;
1680  StringRef MacroDWOSection;
1681  StringRef AbbrevDWOSection;
1682  StringRef StrDWOSection;
1683  StringRef CUIndexSection;
1684  StringRef GdbIndexSection;
1685  StringRef TUIndexSection;
1686  StringRef LineStrSection;
1687 
1688  // A deque holding section data whose iterators are not invalidated when
1689  // new decompressed sections are inserted at the end.
1690  std::deque<SmallString<0>> UncompressedSections;
1691 
1692  StringRef *mapSectionToMember(StringRef Name) {
1693  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
1694  return &Sec->Data;
1695  return StringSwitch<StringRef *>(Name)
1696  .Case("debug_abbrev", &AbbrevSection)
1697  .Case("debug_aranges", &ArangesSection)
1698  .Case("debug_str", &StrSection)
1699  .Case("debug_macinfo", &MacinfoSection)
1700  .Case("debug_macinfo.dwo", &MacinfoDWOSection)
1701  .Case("debug_macro.dwo", &MacroDWOSection)
1702  .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1703  .Case("debug_str.dwo", &StrDWOSection)
1704  .Case("debug_cu_index", &CUIndexSection)
1705  .Case("debug_tu_index", &TUIndexSection)
1706  .Case("gdb_index", &GdbIndexSection)
1707  .Case("debug_line_str", &LineStrSection)
1708  // Any more debug info sections go here.
1709  .Default(nullptr);
1710  }
1711 
1712  /// If Sec is compressed section, decompresses and updates its contents
1713  /// provided by Data. Otherwise leaves it unchanged.
1714  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
1715  StringRef &Data) {
1716  if (!Sec.isCompressed())
1717  return Error::success();
1718 
1719  Expected<Decompressor> Decompressor =
1720  Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1721  if (!Decompressor)
1722  return Decompressor.takeError();
1723 
1724  SmallString<0> Out;
1725  if (auto Err = Decompressor->resizeAndDecompress(Out))
1726  return Err;
1727 
1728  UncompressedSections.push_back(std::move(Out));
1729  Data = UncompressedSections.back();
1730 
1731  return Error::success();
1732  }
1733 
1734 public:
1735  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
1736  uint8_t AddrSize, bool IsLittleEndian)
1737  : IsLittleEndian(IsLittleEndian) {
1738  for (const auto &SecIt : Sections) {
1739  if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
1740  *SectionData = SecIt.second->getBuffer();
1741  else if (SecIt.first() == "debug_info")
1742  // Find debug_info and debug_types data by section rather than name as
1743  // there are multiple, comdat grouped, of these sections.
1744  InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
1745  else if (SecIt.first() == "debug_info.dwo")
1746  InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1747  else if (SecIt.first() == "debug_types")
1748  TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
1749  else if (SecIt.first() == "debug_types.dwo")
1750  TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
1751  }
1752  }
1753  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
1754  function_ref<void(Error)> HandleError,
1755  function_ref<void(Error)> HandleWarning,
1757  : IsLittleEndian(Obj.isLittleEndian()),
1758  AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
1759  Obj(&Obj) {
1760 
1761  StringMap<unsigned> SectionAmountMap;
1762  for (const SectionRef &Section : Obj.sections()) {
1763  StringRef Name;
1764  if (auto NameOrErr = Section.getName())
1765  Name = *NameOrErr;
1766  else
1767  consumeError(NameOrErr.takeError());
1768 
1769  ++SectionAmountMap[Name];
1770  SectionNames.push_back({ Name, true });
1771 
1772  // Skip BSS and Virtual sections, they aren't interesting.
1773  if (Section.isBSS() || Section.isVirtual())
1774  continue;
1775 
1776  // Skip sections stripped by dsymutil.
1777  if (Section.isStripped())
1778  continue;
1779 
1780  StringRef Data;
1781  Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
1782  if (!SecOrErr) {
1783  HandleError(createError("failed to get relocated section: ",
1784  SecOrErr.takeError()));
1785  continue;
1786  }
1787 
1788  // Try to obtain an already relocated version of this section.
1789  // Else use the unrelocated section from the object file. We'll have to
1790  // apply relocations ourselves later.
1791  section_iterator RelocatedSection =
1792  Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
1793  if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
1794  Expected<StringRef> E = Section.getContents();
1795  if (E)
1796  Data = *E;
1797  else
1798  // maybeDecompress below will error.
1799  consumeError(E.takeError());
1800  }
1801 
1802  if (auto Err = maybeDecompress(Section, Name, Data)) {
1803  HandleError(createError("failed to decompress '" + Name + "', ",
1804  std::move(Err)));
1805  continue;
1806  }
1807 
1808  // Compressed sections names in GNU style starts from ".z",
1809  // at this point section is decompressed and we drop compression prefix.
1810  Name = Name.substr(
1811  Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1812 
1813  // Map platform specific debug section names to DWARF standard section
1814  // names.
1815  Name = Obj.mapDebugSectionName(Name);
1816 
1817  if (StringRef *SectionData = mapSectionToMember(Name)) {
1818  *SectionData = Data;
1819  if (Name == "debug_ranges") {
1820  // FIXME: Use the other dwo range section when we emit it.
1821  RangesDWOSection.Data = Data;
1822  } else if (Name == "debug_frame" || Name == "eh_frame") {
1823  if (DWARFSection *S = mapNameToDWARFSection(Name))
1824  S->Address = Section.getAddress();
1825  }
1826  } else if (InfoSectionMap *Sections =
1828  .Case("debug_info", &InfoSections)
1829  .Case("debug_info.dwo", &InfoDWOSections)
1830  .Case("debug_types", &TypesSections)
1831  .Case("debug_types.dwo", &TypesDWOSections)
1832  .Default(nullptr)) {
1833  // Find debug_info and debug_types data by section rather than name as
1834  // there are multiple, comdat grouped, of these sections.
1835  DWARFSectionMap &S = (*Sections)[Section];
1836  S.Data = Data;
1837  }
1838 
1839  if (RelocatedSection != Obj.section_end() && Name.contains(".dwo"))
1840  HandleWarning(
1841  createError("Unexpected relocations for dwo section " + Name));
1842 
1843  if (RelocatedSection == Obj.section_end() ||
1845  continue;
1846 
1847  StringRef RelSecName;
1848  if (auto NameOrErr = RelocatedSection->getName())
1849  RelSecName = *NameOrErr;
1850  else
1851  consumeError(NameOrErr.takeError());
1852 
1853  // If the section we're relocating was relocated already by the JIT,
1854  // then we used the relocated version above, so we do not need to process
1855  // relocations for it now.
1856  StringRef RelSecData;
1857  if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1858  continue;
1859 
1860  // In Mach-o files, the relocations do not need to be applied if
1861  // there is no load offset to apply. The value read at the
1862  // relocation point already factors in the section address
1863  // (actually applying the relocations will produce wrong results
1864  // as the section address will be added twice).
1865  if (!L && isa<MachOObjectFile>(&Obj))
1866  continue;
1867 
1868  RelSecName = RelSecName.substr(
1869  RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
1870 
1871  // TODO: Add support for relocations in other sections as needed.
1872  // Record relocations for the debug_info and debug_line sections.
1873  DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
1874  RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
1875  if (!Map) {
1876  // Find debug_info and debug_types relocs by section rather than name
1877  // as there are multiple, comdat grouped, of these sections.
1878  if (RelSecName == "debug_info")
1879  Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
1880  .Relocs;
1881  else if (RelSecName == "debug_types")
1882  Map =
1883  &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
1884  .Relocs;
1885  else
1886  continue;
1887  }
1888 
1889  if (Section.relocation_begin() == Section.relocation_end())
1890  continue;
1891 
1892  // Symbol to [address, section index] cache mapping.
1893  std::map<SymbolRef, SymInfo> AddrCache;
1894  SupportsRelocation Supports;
1896  std::tie(Supports, Resolver) = getRelocationResolver(Obj);
1897  for (const RelocationRef &Reloc : Section.relocations()) {
1898  // FIXME: it's not clear how to correctly handle scattered
1899  // relocations.
1900  if (isRelocScattered(Obj, Reloc))
1901  continue;
1902 
1903  Expected<SymInfo> SymInfoOrErr =
1904  getSymbolInfo(Obj, Reloc, L, AddrCache);
1905  if (!SymInfoOrErr) {
1906  HandleError(SymInfoOrErr.takeError());
1907  continue;
1908  }
1909 
1910  // Check if Resolver can handle this relocation type early so as not to
1911  // handle invalid cases in DWARFDataExtractor.
1912  //
1913  // TODO Don't store Resolver in every RelocAddrEntry.
1914  if (Supports && Supports(Reloc.getType())) {
1915  auto I = Map->try_emplace(
1916  Reloc.getOffset(),
1918  SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
1919  std::optional<object::RelocationRef>(), 0, Resolver});
1920  // If we didn't successfully insert that's because we already had a
1921  // relocation for that offset. Store it as a second relocation in the
1922  // same RelocAddrEntry instead.
1923  if (!I.second) {
1924  RelocAddrEntry &entry = I.first->getSecond();
1925  if (entry.Reloc2) {
1926  HandleError(createError(
1927  "At most two relocations per offset are supported"));
1928  }
1929  entry.Reloc2 = Reloc;
1930  entry.SymbolValue2 = SymInfoOrErr->Address;
1931  }
1932  } else {
1934  Reloc.getTypeName(Type);
1935  // FIXME: Support more relocations & change this to an error
1936  HandleWarning(
1937  createError("failed to compute relocation: " + Type + ", ",
1938  errorCodeToError(object_error::parse_failed)));
1939  }
1940  }
1941  }
1942 
1943  for (SectionName &S : SectionNames)
1944  if (SectionAmountMap[S.Name] > 1)
1945  S.IsNameUnique = false;
1946  }
1947 
1948  std::optional<RelocAddrEntry> find(const DWARFSection &S,
1949  uint64_t Pos) const override {
1950  auto &Sec = static_cast<const DWARFSectionMap &>(S);
1951  RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
1952  if (AI == Sec.Relocs.end())
1953  return std::nullopt;
1954  return AI->second;
1955  }
1956 
1957  const object::ObjectFile *getFile() const override { return Obj; }
1958 
1959  ArrayRef<SectionName> getSectionNames() const override {
1960  return SectionNames;
1961  }
1962 
1963  bool isLittleEndian() const override { return IsLittleEndian; }
1964  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
1965  const DWARFSection &getLineDWOSection() const override {
1966  return LineDWOSection;
1967  }
1968  const DWARFSection &getLocDWOSection() const override {
1969  return LocDWOSection;
1970  }
1971  StringRef getStrDWOSection() const override { return StrDWOSection; }
1972  const DWARFSection &getStrOffsetsDWOSection() const override {
1973  return StrOffsetsDWOSection;
1974  }
1975  const DWARFSection &getRangesDWOSection() const override {
1976  return RangesDWOSection;
1977  }
1978  const DWARFSection &getRnglistsDWOSection() const override {
1979  return RnglistsDWOSection;
1980  }
1981  const DWARFSection &getLoclistsDWOSection() const override {
1982  return LoclistsDWOSection;
1983  }
1984  const DWARFSection &getAddrSection() const override { return AddrSection; }
1985  StringRef getCUIndexSection() const override { return CUIndexSection; }
1986  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
1987  StringRef getTUIndexSection() const override { return TUIndexSection; }
1988 
1989  // DWARF v5
1990  const DWARFSection &getStrOffsetsSection() const override {
1991  return StrOffsetsSection;
1992  }
1993  StringRef getLineStrSection() const override { return LineStrSection; }
1994 
1995  // Sections for DWARF5 split dwarf proposal.
1996  void forEachInfoDWOSections(
1997  function_ref<void(const DWARFSection &)> F) const override {
1998  for (auto &P : InfoDWOSections)
1999  F(P.second);
2000  }
2001  void forEachTypesDWOSections(
2002  function_ref<void(const DWARFSection &)> F) const override {
2003  for (auto &P : TypesDWOSections)
2004  F(P.second);
2005  }
2006 
2007  StringRef getAbbrevSection() const override { return AbbrevSection; }
2008  const DWARFSection &getLocSection() const override { return LocSection; }
2009  const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
2010  StringRef getArangesSection() const override { return ArangesSection; }
2011  const DWARFSection &getFrameSection() const override {
2012  return FrameSection;
2013  }
2014  const DWARFSection &getEHFrameSection() const override {
2015  return EHFrameSection;
2016  }
2017  const DWARFSection &getLineSection() const override { return LineSection; }
2018  StringRef getStrSection() const override { return StrSection; }
2019  const DWARFSection &getRangesSection() const override { return RangesSection; }
2020  const DWARFSection &getRnglistsSection() const override {
2021  return RnglistsSection;
2022  }
2023  const DWARFSection &getMacroSection() const override { return MacroSection; }
2024  StringRef getMacroDWOSection() const override { return MacroDWOSection; }
2025  StringRef getMacinfoSection() const override { return MacinfoSection; }
2026  StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
2027  const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
2028  const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
2029  const DWARFSection &getGnuPubnamesSection() const override {
2030  return GnuPubnamesSection;
2031  }
2032  const DWARFSection &getGnuPubtypesSection() const override {
2033  return GnuPubtypesSection;
2034  }
2035  const DWARFSection &getAppleNamesSection() const override {
2036  return AppleNamesSection;
2037  }
2038  const DWARFSection &getAppleTypesSection() const override {
2039  return AppleTypesSection;
2040  }
2041  const DWARFSection &getAppleNamespacesSection() const override {
2042  return AppleNamespacesSection;
2043  }
2044  const DWARFSection &getAppleObjCSection() const override {
2045  return AppleObjCSection;
2046  }
2047  const DWARFSection &getNamesSection() const override {
2048  return NamesSection;
2049  }
2050 
2051  StringRef getFileName() const override { return FileName; }
2052  uint8_t getAddressSize() const override { return AddressSize; }
2053  void forEachInfoSections(
2054  function_ref<void(const DWARFSection &)> F) const override {
2055  for (auto &P : InfoSections)
2056  F(P.second);
2057  }
2058  void forEachTypesSections(
2059  function_ref<void(const DWARFSection &)> F) const override {
2060  for (auto &P : TypesSections)
2061  F(P.second);
2062  }
2063 };
2064 } // namespace
2065 
2066 std::unique_ptr<DWARFContext>
2068  ProcessDebugRelocations RelocAction,
2069  const LoadedObjectInfo *L, std::string DWPName,
2070  std::function<void(Error)> RecoverableErrorHandler,
2071  std::function<void(Error)> WarningHandler) {
2072  auto DObj = std::make_unique<DWARFObjInMemory>(
2073  Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
2074  return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
2075  RecoverableErrorHandler,
2076  WarningHandler);
2077 }
2078 
2079 std::unique_ptr<DWARFContext>
2080 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
2081  uint8_t AddrSize, bool isLittleEndian,
2082  std::function<void(Error)> RecoverableErrorHandler,
2083  std::function<void(Error)> WarningHandler) {
2084  auto DObj =
2085  std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
2086  return std::make_unique<DWARFContext>(
2087  std::move(DObj), "", RecoverableErrorHandler, WarningHandler);
2088 }
2089 
2091  // In theory, different compile units may have different address byte
2092  // sizes, but for simplicity we just use the address byte size of the
2093  // first compile unit. In practice the address size field is repeated across
2094  // various DWARF headers (at least in version 5) to make it easier to dump
2095  // them independently, not to enable varying the address size.
2096  auto CUs = compile_units();
2097  return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
2098 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
i
i
Definition: README.txt:29
llvm::DWARFDebugRangeList
Definition: DWARFDebugRangeList.h:24
MemoryBuffer.h
llvm::DWARFSection
Definition: DWARFSection.h:16
set
We currently generate a but we really shouldn eax ecx xorl edx divl ecx eax divl ecx movl eax ret A similar code sequence works for division We currently compile i32 v2 eax eax jo LBB1_2 atomic and others It is also currently not done for read modify write instructions It is also current not done if the OF or CF flags are needed The shift operators have the complication that when the shift count is EFLAGS is not set
Definition: README.txt:1277
DWARFFormValue.h
llvm::DWARFContext::getDebugNames
const DWARFDebugNames & getDebugNames()
Get a reference to the parsed accelerator table object.
Definition: DWARFContext.cpp:1009
llvm::errc::invalid_argument
@ invalid_argument
llvm::logicalview::LVAttributeKind::Local
@ Local
llvm::DWARFContext::getLineTableForUnit
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
Definition: DWARFContext.cpp:1036
llvm::DWARFDie::isValid
bool isValid() const
Definition: DWARFDie.h:50
dumpLoclistsSection
static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const DWARFObject &Obj, std::optional< uint64_t > DumpOffset)
Definition: DWARFContext.cpp:310
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::DWARFVerifier
A class that verifies DWARF debug information given a DWARF Context.
Definition: DWARFVerifier.h:34
DWARFCompileUnit.h
llvm::DWARFContext::types_section_units
unit_iterator_range types_section_units()
Get units from .debug_types in this context.
Definition: DWARFContext.h:161
llvm::DWARFDebugLine::SectionParser::getOffset
uint64_t getOffset() const
Get the offset the parser has reached.
Definition: DWARFDebugLine.h:353
llvm::LoadedObjectInfo::getLoadedSectionContents
virtual bool getLoadedSectionContents(const object::SectionRef &Sec, StringRef &Data) const
If conveniently available, return the content of the given Section.
Definition: DIContext.h:297
llvm::DWARFContext::create
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler)
Definition: DWARFContext.cpp:2067
llvm::sys::path::extension
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
Definition: Path.cpp:590
llvm::DWARFContext::getEHFrame
Expected< const DWARFDebugFrame * > getEHFrame()
Get a pointer to the parsed eh frame information object.
Definition: DWARFContext.cpp:955
llvm::COFF::SectionSize
@ SectionSize
Definition: COFF.h:60
DWARFGdbIndex.h
DWARFAcceleratorTable.h
llvm::object::RelocationResolver
uint64_t(*)(uint64_t Type, uint64_t Offset, uint64_t S, uint64_t LocData, int64_t Addend) RelocationResolver
Definition: RelocationResolver.h:30
llvm::DWARFDebugAranges::findAddress
uint64_t findAddress(uint64_t Address) const
Definition: DWARFDebugAranges.cpp:124
DWARFDebugMacro.h
llvm::DWARFDebugPubTable::dump
void dump(raw_ostream &OS) const
Definition: DWARFDebugPubTable.cpp:93
T
llvm::DIInliningInfo
A format-neutral container for inlined code description.
Definition: DIContext.h:88
llvm::DILineInfoSpecifier
Controls which fields of DILineInfo container should be filled with data.
Definition: DIContext.h:140
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::DWARFContext::getAppleNames
const AppleAcceleratorTable & getAppleNames()
Get a reference to the parsed accelerator table object.
Definition: DWARFContext.cpp:1014
llvm::DWARFDebugLine::SectionParser::done
bool done() const
Indicates if the parser has parsed as much as possible.
Definition: DWARFDebugLine.h:350
llvm::DIDumpOptions::DumpType
unsigned DumpType
Definition: DIContext.h:190
llvm::AppleAcceleratorTable::dump
void dump(raw_ostream &OS) const override
Definition: DWARFAcceleratorTable.cpp:202
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::dwarf::toUnsigned
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Definition: DWARFFormValue.h:225
Path.h
llvm::DWARFContext::getNumTypeUnits
unsigned getNumTypeUnits()
Get the number of type units in this context.
Definition: DWARFContext.h:222
llvm::raw_ostream::write_escaped
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
Definition: raw_ostream.cpp:161
llvm::DWARFContext::getDWOCompileUnitForHash
DWARFCompileUnit * getDWOCompileUnitForHash(uint64_t Hash)
Definition: DWARFContext.cpp:728
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
MapVector.h
llvm::DWARFContext::getLineInfoForAddressRange
DILineInfoTable getLineInfoForAddressRange(object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: DWARFContext.cpp:1346
DWARFDebugLine.h
DWARFContext.h
Error.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::DILineInfo::BadString
static constexpr const char *const BadString
Definition: DIContext.h:34
llvm::DWARFContext::getStringExtractor
DataExtractor getStringExtractor() const
Definition: DWARFContext.h:340
llvm::DWARFUnitVector::addUnitsForSection
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind)
Read units from a .debug_info or .debug_types section.
Definition: DWARFUnit.cpp:42
llvm::DenseMapIterator
Definition: DenseMap.h:57
llvm::DWARFContext::info_section_units
unit_iterator_range info_section_units()
Get units from .debug_info in this context.
Definition: DWARFContext.h:148
llvm::DWARFUnitVector::addUnitsForDWOSection
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:53
llvm::DWARFContext
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:46
llvm::DIDumpOptions::WarningHandler
std::function< void(Error)> WarningHandler
Definition: DIContext.h:226
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DWARFRelocMap.h
llvm::DWARFUnitIndex::Entry
Definition: DWARFUnitIndex.h:111
getSymbolInfo
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.
Definition: DWARFContext.cpp:1533
llvm::DWARFContext::getLineInfoForDataAddress
DILineInfo getLineInfoForDataAddress(object::SectionedAddress Address) override
Definition: DWARFContext.cpp:1332
getAccelTable
static T & getAccelTable(std::unique_ptr< T > &Cache, const DWARFObject &Obj, const DWARFSection &Section, StringRef StringSection, bool IsLittleEndian)
Definition: DWARFContext.cpp:996
llvm::dwarf::toSectionedAddress
std::optional< object::SectionedAddress > toSectionedAddress(const std::optional< DWARFFormValue > &V)
Definition: DWARFFormValue.h:300
llvm::MapVector
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
llvm::DWARFContext::getDebugAbbrevDWO
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
Definition: DWARFContext.cpp:896
llvm::DWARFUnitIndex::dump
void dump(raw_ostream &OS) const
Definition: DWARFUnitIndex.cpp:215
llvm::DIE
A structured debug information entry.
Definition: DIE.h:739
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
DWARFDebugArangeSet.h
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
llvm::DWARFDebugAddrTable::extract
Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, uint16_t CUVersion, uint8_t CUAddrSize, std::function< void(Error)> WarnCallback)
Extract the entire table, including all addresses.
Definition: DWARFDebugAddr.cpp:122
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::DWARFUnitIndex::Entry::SectionContribution::setOffset
void setOffset(uint64_t Value)
Definition: DWARFUnitIndex.h:123
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::DWARFContext::dwo_types_section_units
unit_iterator_range dwo_types_section_units()
Get units from .debug_types.dwo in the DWO context.
Definition: DWARFContext.h:194
STLExtras.h
llvm::DWARFDie::find
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:247
llvm::DIE::getTag
dwarf::Tag getTag() const
Definition: DIE.h:775
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::DWARFDebugLine::LineTable::getFileLineInfoForAddress
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.
Definition: DWARFDebugLine.cpp:1406
llvm::DWARFVerifier::handleDebugInfo
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
Definition: DWARFVerifier.cpp:451
Format.h
llvm::DWARFContext::getLocalsForAddress
std::vector< DILocal > getLocalsForAddress(object::SectionedAddress Address) override
Definition: DWARFContext.cpp:1298
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::DWARFContext::getDebugMacroDWO
const DWARFDebugMacro * getDebugMacroDWO()
Get a pointer to the parsed DebugMacroDWO information object.
Definition: DWARFContext.cpp:977
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::DILineInfo::StartAddress
std::optional< uint64_t > StartAddress
Definition: DIContext.h:44
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:160
F
#define F(x, y, z)
Definition: MD5.cpp:55
MachO.h
llvm::DWARFContext::getInliningInfoForAddress
DIInliningInfo getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: DWARFContext.cpp:1401
llvm::DILineInfo::FunctionName
std::string FunctionName
Definition: DIContext.h:38
llvm::DWARFContext::getAppleObjC
const AppleAcceleratorTable & getAppleObjC()
Get a reference to the parsed accelerator table object.
Definition: DWARFContext.cpp:1030
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:426
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::Resolver
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:2137
SymInfo::SectionIndex
uint64_t SectionIndex
Definition: DWARFContext.cpp:1528
llvm::object::SymbolicFile::symbol_end
virtual basic_symbol_iterator symbol_end() const =0
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::DWARFContext::getDebugMacinfo
const DWARFDebugMacro * getDebugMacinfo()
Get a pointer to the parsed DebugMacinfo information object.
Definition: DWARFContext.cpp:983
llvm::DWARFDebugLoc::dump
void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, std::optional< uint64_t > Offset) const
Print the location lists found within the debug_loc section.
Definition: DWARFDebugLoc.cpp:185
llvm::DILineInfo::Column
uint32_t Column
Definition: DIContext.h:42
llvm::DWARFContext::getDebugAranges
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
Definition: DWARFContext.cpp:920
getExpressionFrameOffset
static std::optional< int64_t > getExpressionFrameOffset(ArrayRef< uint8_t > Expr, std::optional< unsigned > FrameBaseReg)
Definition: DWARFContext.cpp:1214
dumpAddrSection
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize)
Definition: DWARFContext.cpp:222
DWARFDebugRangeList.h
DWARFVerifier.h
llvm::DWARFDebugLine::Row
Standard .debug_line state machine structure.
Definition: DWARFDebugLine.h:132
llvm::object::ObjectFile::isRelocatableObject
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
llvm::DIDumpOptions::Verbose
bool Verbose
Definition: DIContext.h:200
llvm::DINameKind
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:136
llvm::DWARFDebugLoclists
Definition: DWARFDebugLoc.h:124
llvm::DWARFDataExtractor::getRelocatedValue
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset.
Definition: DWARFDataExtractor.cpp:48
llvm::msgpack::Type::Map
@ Map
llvm::object::ObjectFile::section_end
virtual section_iterator section_end() const =0
DWARFDebugFrame.h
SmallString.h
llvm::DWARFContext::dwo_info_section_units
unit_iterator_range dwo_info_section_units()
Get units from .debug_info..dwo in the DWO context.
Definition: DWARFContext.h:182
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::DWARFContext::getDebugMacinfoDWO
const DWARFDebugMacro * getDebugMacinfoDWO()
Get a pointer to the parsed DebugMacinfoDWO information object.
Definition: DWARFContext.cpp:989
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::DWARFDebugAbbrev
Definition: DWARFDebugAbbrev.h:56
llvm::DWARFContext::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, std::array< std::optional< uint64_t >, DIDT_ID_Count > DumpOffsets)
Dump a textual representation to OS.
Definition: DWARFContext.cpp:349
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:92
llvm::DWARFUnitIndex
Definition: DWARFUnitIndex.h:99
llvm::DIInliningInfo::addFrame
void addFrame(const DILineInfo &Frame)
Definition: DIContext.h:108
DWARFSection.h
llvm::DWARFContext::getMaxVersion
unsigned getMaxVersion()
Definition: DWARFContext.h:260
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::DIContext
Definition: DIContext.h:229
llvm::DWARFUnitIndex::Entry::SectionContribution::getOffset
uint64_t getOffset() const
Definition: DWARFUnitIndex.h:125
getFileName
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
Definition: CodeViewYAMLDebugSections.cpp:555
llvm::StringRef::substr
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:559
llvm::DWARFContext::getNumCompileUnits
unsigned getNumCompileUnits()
Get the number of compile units in this context.
Definition: DWARFContext.h:216
DWARFDie.h
llvm::dwarf::Index
Index
Definition: Dwarf.h:550
llvm::createError
static Error createError(const Twine &Err)
Definition: APFloat.cpp:261
DWARFDebugLoc.h
llvm::DWARFDie::getCallerFrame
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:481
llvm::DWARFContext::getArch
Triple::ArchType getArch() const
Definition: DWARFContext.h:440
dumpUUID
static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj)
Dump the UUID load command.
Definition: DWARFContext.cpp:83
llvm::DWARFLocationTable::dumpLocationList
bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, std::optional< object::SectionedAddress > BaseAddr, const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts, unsigned Indent) const
Dump the location list at the given Offset.
Definition: DWARFDebugLoc.cpp:123
llvm::DWARFDie::getDeclFile
std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
Definition: DWARFDie.cpp:474
llvm::DWARFListTableBase::length
uint64_t length()
Definition: DWARFListTable.h:200
llvm::dwarf::FormatString
StringRef FormatString(DwarfFormat Format)
Definition: Dwarf.cpp:791
llvm::dwarf::toString
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:176
llvm::DWARFVerifier::handleDebugLine
bool handleDebugLine()
Verify the information in the .debug_line section.
Definition: DWARFVerifier.cpp:960
llvm::DWARFDebugLine::LineTable::Rows
RowVector Rows
Definition: DWARFDebugLine.h:290
llvm::DW_SECT_EXT_TYPES
@ DW_SECT_EXT_TYPES
Definition: DWARFUnitIndex.h:62
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::DWARFObject
Definition: DWARFObject.h:26
llvm::DILineInfo::StartLine
uint32_t StartLine
Definition: DIContext.h:43
DWARFListTable.h
llvm::DWARFDebugLine::SectionParser::parseNext
LineTable parseNext(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler, raw_ostream *OS=nullptr, bool Verbose=false)
Get the next line table from the section.
Definition: DWARFDebugLine.cpp:1469
llvm::DWARFUnit::getLineTableOffset
uint32_t getLineTableOffset() const
Definition: DWARFUnit.h:536
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1058
ContributionCollection
std::vector< std::optional< StrOffsetsContributionDescriptor > > ContributionCollection
Definition: DWARFContext.cpp:105
llvm::DWARFContext::getStringDWOExtractor
DataExtractor getStringDWOExtractor() const
Definition: DWARFContext.h:343
llvm::DWARFUnit::getLineSection
const DWARFSection & getLineSection() const
Definition: DWARFUnit.h:332
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:91
SymInfo::Address
uint64_t Address
Definition: DWARFContext.cpp:1527
llvm::DWARFContext::ProcessDebugRelocations::Ignore
@ Ignore
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::DWARFDebugLine::LineTable::lookupAddressRange
bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size, std::vector< uint32_t > &Result) const
Definition: DWARFDebugLine.cpp:1270
llvm::DWARFContext::compile_units
compile_unit_range compile_units()
Get compile units in this context.
Definition: DWARFContext.h:168
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::DWARFVerifier::handleAccelTables
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
Definition: DWARFVerifier.cpp:1608
llvm::DWARFDebugLine
Definition: DWARFDebugLine.h:28
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
llvm::SmallString< 128 >
llvm::DWARFContext::getDebugMacro
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro information object.
Definition: DWARFContext.cpp:971
llvm::DWARFContext::dwo_units
unit_iterator_range dwo_units()
Get all units in the DWO context.
Definition: DWARFContext.h:210
llvm::DWARFContext::verify
bool verify(raw_ostream &OS, DIDumpOptions DumpOpts={}) override
Definition: DWARFContext.cpp:765
llvm::DWARFCompileUnit
Definition: DWARFCompileUnit.h:22
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::object::SupportsRelocation
bool(*)(uint64_t) SupportsRelocation
Definition: RelocationResolver.h:27
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1683
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
DWARFDebugPubTable.h
llvm::DWARFDebugRangeList::extract
Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr)
Definition: DWARFDebugRangeList.cpp:31
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::DWARFGdbIndex::dump
void dump(raw_ostream &OS)
Definition: DWARFGdbIndex.cpp:98
collectContributionData
static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units)
Definition: DWARFContext.cpp:110
DWARFDebugAranges.h
llvm::DWARFGdbIndex
Definition: DWARFGdbIndex.h:22
llvm::DIDT_ID_Count
@ DIDT_ID_Count
Definition: DIContext.h:172
llvm::DILineInfo::Line
uint32_t Line
Definition: DIContext.h:41
llvm::DWARFContext::getTypeUnitForHash
DWARFTypeUnit * getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO)
Definition: DWARFContext.cpp:700
llvm::DINameKind::ShortName
@ ShortName
llvm::object::SymbolRef::getSection
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:423
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
dumpPubTableSection
static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, bool GnuStyle)
Definition: DWARFContext.cpp:342
llvm::DWARFContext::getNumDWOTypeUnits
unsigned getNumDWOTypeUnits()
Get the number of type units in the DWO context.
Definition: DWARFContext.h:234
llvm::LoadedObjectInfo::getSectionLoadAddress
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const
Obtain the Load Address of a section by SectionRef.
Definition: DIContext.h:282
llvm::DWARFDebugLine::LineTable::getFileNameByIndex
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
Definition: DWARFDebugLine.h:257
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
llvm::DWARFDebugLoc
Definition: DWARFDebugLoc.h:88
llvm::DWARFDebugRnglistTable
Definition: DWARFDebugRnglists.h:62
uint64_t
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::DWARFDebugLine::SectionParser
Helper to allow for parsing of an entire .debug_line section in sequence.
Definition: DWARFDebugLine.h:314
llvm::DWARFVerifier::handleDebugAbbrev
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
Definition: DWARFVerifier.cpp:322
llvm::DWARFDie::getDeclLine
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:469
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1755
llvm::DWARFDebugAddrTable
A class representing an address table as specified in DWARF v5.
Definition: DWARFDebugAddr.h:26
llvm::DWARFContext::getDebugAbbrev
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
Definition: DWARFContext.cpp:885
LEB128.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DWARFContext::clearLineTableForUnit
void clearLineTableForUnit(DWARFUnit *U)
Definition: DWARFContext.cpp:1075
llvm::DenseMap
Definition: DenseMap.h:714
llvm::DWARFContext::getCUAddrSize
uint8_t getCUAddrSize()
Get address size from CUs.
Definition: DWARFContext.cpp:2090
llvm::DWARFUnitIndex::Entry::SectionContribution
Definition: DWARFUnitIndex.h:113
llvm::DWARFContext::dwo_compile_units
compile_unit_range dwo_compile_units()
Get compile units in the DWO context.
Definition: DWARFContext.h:201
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::DILineInfo
A format-neutral container for source line information.
Definition: DIContext.h:32
llvm::DILineInfoSpecifier::FileLineInfoKind
FileLineInfoKind
Definition: DIContext.h:141
getFunctionNameAndStartLineForAddress
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, DILineInfoSpecifier::FileLineInfoKind FileNameKind, std::string &FunctionName, std::string &StartFile, uint32_t &StartLine, std::optional< uint64_t > &StartAddress)
TODO: change input parameter from "uint64_t Address" into "SectionedAddress Address".
Definition: DWARFContext.cpp:1179
DWARFDebugRnglists.h
fixupIndex
void fixupIndex(const DWARFObject &DObj, DWARFContext &C, DWARFUnitIndex &Index)
Definition: DWARFContext.cpp:782
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:665
llvm::object::ObjectFile::createObjectFile
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:194
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1862
ObjectFile.h
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::DWARFDebugArangeSet
Definition: DWARFDebugArangeSet.h:23
llvm::object::content_iterator
Definition: SymbolicFile.h:69
llvm::DWARFContext::getUnitAtIndex
DWARFUnit * getUnitAtIndex(unsigned index)
Get the unit at the specified index.
Definition: DWARFContext.h:240
llvm::StringRef::find_first_not_of
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:251
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::Length
@ Length
Definition: DWP.cpp:406
UUID
std::pair< llvm::MachO::Target, std::string > UUID
Definition: TextStubCommon.h:23
llvm::DWARFListTableBase::dump
void dump(DWARFDataExtractor Data, raw_ostream &OS, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts={}) const
Definition: DWARFListTable.h:254
dumpStringOffsetsSection
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, DWARFContext::unit_iterator_range Units, bool LittleEndian)
Definition: DWARFContext.cpp:149
llvm::DILineInfo::Discriminator
uint32_t Discriminator
Definition: DIContext.h:47
llvm::DWARFContext::getTUIndex
const DWARFUnitIndex & getTUIndex()
Definition: DWARFContext.cpp:861
llvm::object::getRelocationResolver
std::pair< SupportsRelocation, RelocationResolver > getRelocationResolver(const ObjectFile &Obj)
Definition: RelocationResolver.cpp:749
llvm::DWARFContext::getDIEsForAddress
DIEsForAddress getDIEsForAddress(uint64_t Address)
Get the compilation unit, the function DIE and lexical block DIE for the given address where applicab...
Definition: DWARFContext.cpp:1146
llvm::DWARFContext::getGdbIndex
DWARFGdbIndex & getGdbIndex()
Definition: DWARFContext.cpp:875
dumpRnglistsSection
static void dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, llvm::function_ref< std::optional< object::SectionedAddress >(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts)
Definition: DWARFContext.cpp:245
llvm::DWARFContext::getDWOContext
std::shared_ptr< DWARFContext > getDWOContext(StringRef AbsolutePath)
Definition: DWARFContext.cpp:1470
llvm::DIDT_All
@ DIDT_All
Definition: DIContext.h:179
llvm::DWARFUnitVector::getUnitForIndexEntry
DWARFUnit * getUnitForIndexEntry(const DWARFUnitIndex::Entry &E)
Definition: DWARFUnit.cpp:158
llvm::DWARFDie::getLocations
Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition: DWARFDie.cpp:406
llvm::RelocAddrEntry
RelocAddrEntry contains relocated value and section index.
Definition: DWARFRelocMap.h:21
RelocationResolver.h
llvm::DataExtractor::getCStr
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
Definition: DataExtractor.h:129
llvm::DWARFContext::getDebugFrame
Expected< const DWARFDebugFrame * > getDebugFrame()
Get a pointer to the parsed frame information object.
Definition: DWARFContext.cpp:929
llvm::ArrayRef< uint8_t >
llvm::DWARFContext::isLittleEndian
bool isLittleEndian() const
Definition: DWARFContext.h:379
llvm::DWARFContext::getDebugLoc
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
Definition: DWARFContext.cpp:906
llvm::object::section_iterator
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Dwarf.h
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
llvm::Offset
@ Offset
Definition: DWP.cpp:406
llvm::DWARFUnitVector::getUnitForOffset
DWARFUnit * getUnitForOffset(uint64_t Offset) const
Definition: DWARFUnit.cpp:145
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
uint32_t
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:2014
llvm::DWARFContext::normal_units
unit_iterator_range normal_units()
Get all normal compile/type units in this context.
Definition: DWARFContext.h:176
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::unique
auto unique(Range &&R)
Definition: GenericUniformityImpl.h:56
llvm::DWARFVerifier::handleDebugCUIndex
bool handleDebugCUIndex()
Verify the information in the .debug_cu_index section.
Definition: DWARFVerifier.cpp:441
llvm::AppleAcceleratorTable
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
Definition: DWARFAcceleratorTable.h:83
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::DWARFContext::getNumDWOCompileUnits
unsigned getNumDWOCompileUnits()
Get the number of compile units in the DWO context.
Definition: DWARFContext.h:228
llvm::DWARFDebugMacro
Definition: DWARFDebugMacro.h:23
llvm::DWARFVerifier::handleDebugTUIndex
bool handleDebugTUIndex()
Verify the information in the .debug_tu_index section.
Definition: DWARFVerifier.cpp:446
DWARFLocationExpression.h
llvm::DIDT_UUID
@ DIDT_UUID
Definition: DIContext.h:184
llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
@ AbsoluteFilePath
Decompressor.h
llvm::DWARFDebugPubTable
Represents structure for holding and parsing .debug_pub* tables.
Definition: DWARFDebugPubTable.h:26
llvm::DWARFContext::getDIEForOffset
DWARFDie getDIEForOffset(uint64_t Offset)
Get a DIE given an exact offset.
Definition: DWARFContext.cpp:758
llvm::DWARFContext::getCUIndex
const DWARFUnitIndex & getCUIndex()
Definition: DWARFContext.cpp:850
llvm::logAllUnhandledErrors
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:63
llvm::DWARFContext::getLineInfoForAddress
DILineInfo getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
Definition: DWARFContext.cpp:1310
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
llvm::DWARFContext::~DWARFContext
~DWARFContext() override
llvm::DWARFListTableHeader
A class representing the header of a list table such as the range list table in the ....
Definition: DWARFListTable.h:55
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::DWARFObject::getCUIndexSection
virtual StringRef getCUIndexSection() const
Definition: DWARFObject.h:82
llvm::DWARFListTableBase::extract
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr)
Extract an entire table, including all list entries.
Definition: DWARFListTable.h:204
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:319
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1246
llvm::DWARFDebugAddrTable::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts={}) const
Definition: DWARFDebugAddr.cpp:136
llvm::DWARFTypeUnit
Definition: DWARFTypeUnit.h:24
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
llvm::None
constexpr std::nullopt_t None
Definition: None.h:28
uint16_t
DWARFDebugAbbrev.h
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition: DWARFUnitIndex.h:67
llvm::DWARFUnit
Definition: DWARFUnit.h:206
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Success
#define Success
Definition: AArch64Disassembler.cpp:300
llvm::DWARFDebugNames::dump
void dump(raw_ostream &OS) const override
Definition: DWARFAcceleratorTable.cpp:791
llvm::DWARFDebugLoclists::dumpRange
void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts)
Dump all location lists within the given range.
Definition: DWARFDebugLoc.cpp:387
Casting.h
llvm::DWARFContext::getCompileUnitForOffset
DWARFCompileUnit * getCompileUnitForOffset(uint64_t Offset)
Return the compile unit that includes an offset (relative to .debug_info).
Definition: DWARFContext.cpp:1115
DataExtractor.h
llvm::DWARFUnitVector::finishedInfoUnits
void finishedInfoUnits()
Indicate that parsing .debug_info[.dwo] is done, and remaining units will be from ....
Definition: DWARFUnit.h:169
llvm::DILocal
Definition: DIContext.h:124
llvm::DIDumpOptions::DisplayRawContents
bool DisplayRawContents
Definition: DIContext.h:201
DWARFTypeUnit.h
llvm::TargetStackID::Default
@ Default
Definition: TargetFrameLowering.h:28
llvm::Spec
Definition: FunctionSpecialization.h:87
StringSwitch.h
llvm::LoadedObjectInfo
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition: DIContext.h:267
DWARFUnitIndex.h
llvm::DWARFDebugPubTable::extract
void extract(DWARFDataExtractor Data, bool GnuStyle, function_ref< void(Error)> RecoverableErrorHandler)
Definition: DWARFDebugPubTable.cpp:22
createError
static Error createError(const Twine &Reason, llvm::Error E)
Definition: DWARFContext.cpp:1519
llvm::object::ObjectFile::mapDebugSectionName
virtual StringRef mapDebugSectionName(StringRef Name) const
Maps a debug section name to a standard DWARF section name.
Definition: ObjectFile.h:352
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::DWARFDie::getAttributeValueAsReferencedDie
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition: DWARFDie.cpp:304
llvm::decodeSLEB128
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:161
llvm::DILineInfo::FileName
std::string FileName
Definition: DIContext.h:37
llvm::DWARFDebugAddrTable::getFullLength
std::optional< uint64_t > getFullLength() const
Return the full length of this table, including the length field.
Definition: DWARFDebugAddr.cpp:180
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::DWARFDie::getTag
dwarf::Tag getTag() const
Definition: DWARFDie.h:71
SmallVector.h
llvm::DILineInfoSpecifier::FunctionNameKind
DINameKind FunctionNameKind
Definition: DIContext.h:151
llvm::DWARFObject::forEachInfoDWOSections
virtual void forEachInfoDWOSections(function_ref< void(const DWARFSection &)> F) const
Definition: DWARFObject.h:61
llvm::DWARFDebugLine::SectionParser::skip
void skip(function_ref< void(Error)> RecoverableErrorHandler, function_ref< void(Error)> UnrecoverableErrorHandler)
Skip the current line table and go to the following line table (if present) immediately.
Definition: DWARFDebugLine.cpp:1485
llvm::object::SectionedAddress
Definition: ObjectFile.h:144
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::object::ObjectFile::sections
section_iterator_range sections() const
Definition: ObjectFile.h:327
llvm::object::SectionRef::isCompressed
bool isCompressed() const
Definition: ObjectFile.h:489
llvm::DWARFDebugLine::LineTable
Definition: DWARFDebugLine.h:225
SymInfo
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...
Definition: DWARFContext.cpp:1526
llvm::DWARFContext::getCompileUnitForAddress
DWARFCompileUnit * getCompileUnitForAddress(uint64_t Address)
Return the compile unit which contains instruction with provided address.
Definition: DWARFContext.cpp:1121
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:182
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
llvm::DIDumpOptions::noImplicitRecursion
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
Definition: DIContext.h:215
llvm::raw_ostream::uuid_t
uint8_t[16] uuid_t
Output a formatted UUID with dash separators.
Definition: raw_ostream.h:283
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:42
llvm::DWARFDebugNames
.debug_names section consists of one or more units.
Definition: DWARFAcceleratorTable.h:232
llvm::DWARFContext::DWARFContext
DWARFContext(std::unique_ptr< const DWARFObject > DObj, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler)
Definition: DWARFContext.cpp:72
llvm::DWARFDebugAbbrev::dump
void dump(raw_ostream &OS) const
Definition: DWARFDebugAbbrev.cpp:128
llvm::DWARFContext::DIEsForAddress
Wraps the returned DIEs for a given address.
Definition: DWARFContext.h:351
raw_ostream.h
llvm::dwarf::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:718
n
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
Definition: README.txt:685
isRelocScattered
static bool isRelocScattered(const object::ObjectFile &Obj, const RelocationRef &Reloc)
Definition: DWARFContext.cpp:1588
DWARFDebugAddr.h
llvm::dwarf::toSectionOffset
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition: DWARFFormValue.h:323
llvm::DWARFContext::ProcessDebugRelocations
ProcessDebugRelocations
Definition: DWARFContext.h:417
llvm::DWARFDebugAranges
Definition: DWARFDebugAranges.h:23
TargetRegistry.h
llvm::DWARFSection::Data
StringRef Data
Definition: DWARFSection.h:17
CU
Definition: AArch64AsmBackend.cpp:505
llvm::DWARFContext::getAppleTypes
const AppleAcceleratorTable & getAppleTypes()
Get a reference to the parsed accelerator table object.
Definition: DWARFContext.cpp:1019
llvm::raw_ostream::write_uuid
raw_ostream & write_uuid(const uuid_t UUID)
Definition: raw_ostream.cpp:151
llvm::object::SymbolRef::getAddress
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:407
llvm::DWARFContext::getAppleNamespaces
const AppleAcceleratorTable & getAppleNamespaces()
Get a reference to the parsed accelerator table object.
Definition: DWARFContext.cpp:1024
llvm::ArrayRef::end
iterator end() const
Definition: ArrayRef.h:152
entry
print Instructions which execute on loop entry
Definition: MustExecute.cpp:346
llvm::DWARFDebugRangeList::dump
void dump(raw_ostream &OS) const
Definition: DWARFDebugRangeList.cpp:67
llvm::MachO::SectionType
SectionType
These are the section type and attributes fields.
Definition: MachO.h:122
llvm::dwarf::DWARF32
@ DWARF32
Definition: Dwarf.h:91
llvm::DWARFDie::getSubroutineName
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:436
DWARFDataExtractor.h
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:189
llvm::DIDumpOptions::RecoverableErrorHandler
std::function< void(Error)> RecoverableErrorHandler
Definition: DIContext.h:224
llvm::DWARFUnitVector
Describe a collection of units.
Definition: DWARFUnit.h:123
llvm::DILineInfo::StartFileName
std::string StartFileName
Definition: DIContext.h:39