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