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