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