xref: /freebsd-src/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DWARFContext.cpp ---------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFContext.h"
1081ad6265SDimitry Andric #include "llvm/ADT/MapVector.h"
110b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
120b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
130b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
160b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
180b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
1981ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
220b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
240b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
250b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
260b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
270b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
280b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
290b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
300b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
310b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDie.h"
320b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
330b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
3481ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
3581ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
3681ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
370b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFSection.h"
3881ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
390b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
400b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
41349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
420b57cec5SDimitry Andric #include "llvm/Object/Decompressor.h"
430b57cec5SDimitry Andric #include "llvm/Object/MachO.h"
440b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
450b57cec5SDimitry Andric #include "llvm/Object/RelocationResolver.h"
460b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
470b57cec5SDimitry Andric #include "llvm/Support/DataExtractor.h"
480b57cec5SDimitry Andric #include "llvm/Support/Error.h"
490b57cec5SDimitry Andric #include "llvm/Support/Format.h"
500b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
5106c3fb27SDimitry Andric #include "llvm/Support/FormatVariadic.h"
520b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
530b57cec5SDimitry Andric #include "llvm/Support/Path.h"
540b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
550b57cec5SDimitry Andric #include <algorithm>
560b57cec5SDimitry Andric #include <cstdint>
570b57cec5SDimitry Andric #include <deque>
580b57cec5SDimitry Andric #include <map>
590b57cec5SDimitry Andric #include <string>
600b57cec5SDimitry Andric #include <utility>
610b57cec5SDimitry Andric #include <vector>
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric using namespace llvm;
640b57cec5SDimitry Andric using namespace dwarf;
650b57cec5SDimitry Andric using namespace object;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric #define DEBUG_TYPE "dwarf"
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric using DWARFLineTable = DWARFDebugLine::LineTable;
700b57cec5SDimitry Andric using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
710b57cec5SDimitry Andric using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
720b57cec5SDimitry Andric 
735f757f3fSDimitry Andric 
745f757f3fSDimitry Andric void fixupIndexV4(DWARFContext &C, DWARFUnitIndex &Index) {
755f757f3fSDimitry Andric   using EntryType = DWARFUnitIndex::Entry::SectionContribution;
765f757f3fSDimitry Andric   using EntryMap = DenseMap<uint32_t, EntryType>;
775f757f3fSDimitry Andric   EntryMap Map;
785f757f3fSDimitry Andric   const auto &DObj = C.getDWARFObj();
795f757f3fSDimitry Andric   if (DObj.getCUIndexSection().empty())
805f757f3fSDimitry Andric     return;
815f757f3fSDimitry Andric 
825f757f3fSDimitry Andric   uint64_t Offset = 0;
835f757f3fSDimitry Andric   uint32_t TruncOffset = 0;
845f757f3fSDimitry Andric   DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
855f757f3fSDimitry Andric     if (!(C.getParseCUTUIndexManually() ||
865f757f3fSDimitry Andric           S.Data.size() >= std::numeric_limits<uint32_t>::max()))
875f757f3fSDimitry Andric       return;
885f757f3fSDimitry Andric 
895f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
905f757f3fSDimitry Andric     while (Data.isValidOffset(Offset)) {
915f757f3fSDimitry Andric       DWARFUnitHeader Header;
925f757f3fSDimitry Andric       if (Error ExtractionErr = Header.extract(
935f757f3fSDimitry Andric               C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
945f757f3fSDimitry Andric         C.getWarningHandler()(
955f757f3fSDimitry Andric             createError("Failed to parse CU header in DWP file: " +
965f757f3fSDimitry Andric                         toString(std::move(ExtractionErr))));
975f757f3fSDimitry Andric         Map.clear();
985f757f3fSDimitry Andric         break;
995f757f3fSDimitry Andric       }
1005f757f3fSDimitry Andric 
1015f757f3fSDimitry Andric       auto Iter = Map.insert({TruncOffset,
1025f757f3fSDimitry Andric                               {Header.getOffset(), Header.getNextUnitOffset() -
1035f757f3fSDimitry Andric                                                        Header.getOffset()}});
1045f757f3fSDimitry Andric       if (!Iter.second) {
1055f757f3fSDimitry Andric         logAllUnhandledErrors(
1065f757f3fSDimitry Andric             createError("Collision occured between for truncated offset 0x" +
1075f757f3fSDimitry Andric                         Twine::utohexstr(TruncOffset)),
1085f757f3fSDimitry Andric             errs());
1095f757f3fSDimitry Andric         Map.clear();
1105f757f3fSDimitry Andric         return;
1115f757f3fSDimitry Andric       }
1125f757f3fSDimitry Andric 
1135f757f3fSDimitry Andric       Offset = Header.getNextUnitOffset();
1145f757f3fSDimitry Andric       TruncOffset = Offset;
1155f757f3fSDimitry Andric     }
1165f757f3fSDimitry Andric   });
1175f757f3fSDimitry Andric 
1185f757f3fSDimitry Andric   if (Map.empty())
1195f757f3fSDimitry Andric     return;
1205f757f3fSDimitry Andric 
1215f757f3fSDimitry Andric   for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
1225f757f3fSDimitry Andric     if (!E.isValid())
1235f757f3fSDimitry Andric       continue;
1245f757f3fSDimitry Andric     DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
1255f757f3fSDimitry Andric     auto Iter = Map.find(CUOff.getOffset());
1265f757f3fSDimitry Andric     if (Iter == Map.end()) {
1275f757f3fSDimitry Andric       logAllUnhandledErrors(createError("Could not find CU offset 0x" +
1285f757f3fSDimitry Andric                                         Twine::utohexstr(CUOff.getOffset()) +
1295f757f3fSDimitry Andric                                         " in the Map"),
1305f757f3fSDimitry Andric                             errs());
1315f757f3fSDimitry Andric       break;
1325f757f3fSDimitry Andric     }
1335f757f3fSDimitry Andric     CUOff.setOffset(Iter->second.getOffset());
1345f757f3fSDimitry Andric     if (CUOff.getOffset() != Iter->second.getOffset())
1355f757f3fSDimitry Andric       logAllUnhandledErrors(createError("Length of CU in CU index doesn't "
1365f757f3fSDimitry Andric                                         "match calculated length at offset 0x" +
1375f757f3fSDimitry Andric                                         Twine::utohexstr(CUOff.getOffset())),
1385f757f3fSDimitry Andric                             errs());
1395f757f3fSDimitry Andric   }
1405f757f3fSDimitry Andric }
1415f757f3fSDimitry Andric 
1425f757f3fSDimitry Andric void fixupIndexV5(DWARFContext &C, DWARFUnitIndex &Index) {
1435f757f3fSDimitry Andric   DenseMap<uint64_t, uint64_t> Map;
1445f757f3fSDimitry Andric 
1455f757f3fSDimitry Andric   const auto &DObj = C.getDWARFObj();
1465f757f3fSDimitry Andric   DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
1475f757f3fSDimitry Andric     if (!(C.getParseCUTUIndexManually() ||
1485f757f3fSDimitry Andric           S.Data.size() >= std::numeric_limits<uint32_t>::max()))
1495f757f3fSDimitry Andric       return;
1505f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0);
1515f757f3fSDimitry Andric     uint64_t Offset = 0;
1525f757f3fSDimitry Andric     while (Data.isValidOffset(Offset)) {
1535f757f3fSDimitry Andric       DWARFUnitHeader Header;
1545f757f3fSDimitry Andric       if (Error ExtractionErr = Header.extract(
1555f757f3fSDimitry Andric               C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) {
1565f757f3fSDimitry Andric         C.getWarningHandler()(
1575f757f3fSDimitry Andric             createError("Failed to parse CU header in DWP file: " +
1585f757f3fSDimitry Andric                         toString(std::move(ExtractionErr))));
1595f757f3fSDimitry Andric         break;
1605f757f3fSDimitry Andric       }
1615f757f3fSDimitry Andric       bool CU = Header.getUnitType() == DW_UT_split_compile;
1625f757f3fSDimitry Andric       uint64_t Sig = CU ? *Header.getDWOId() : Header.getTypeHash();
1635f757f3fSDimitry Andric       Map[Sig] = Header.getOffset();
1645f757f3fSDimitry Andric       Offset = Header.getNextUnitOffset();
1655f757f3fSDimitry Andric     }
1665f757f3fSDimitry Andric   });
1675f757f3fSDimitry Andric   if (Map.empty())
1685f757f3fSDimitry Andric     return;
1695f757f3fSDimitry Andric   for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) {
1705f757f3fSDimitry Andric     if (!E.isValid())
1715f757f3fSDimitry Andric       continue;
1725f757f3fSDimitry Andric     DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution();
1735f757f3fSDimitry Andric     auto Iter = Map.find(E.getSignature());
1745f757f3fSDimitry Andric     if (Iter == Map.end()) {
1755f757f3fSDimitry Andric       logAllUnhandledErrors(
1765f757f3fSDimitry Andric           createError("Could not find unit with signature 0x" +
1775f757f3fSDimitry Andric                       Twine::utohexstr(E.getSignature()) + " in the Map"),
1785f757f3fSDimitry Andric           errs());
1795f757f3fSDimitry Andric       break;
1805f757f3fSDimitry Andric     }
1815f757f3fSDimitry Andric     CUOff.setOffset(Iter->second);
1825f757f3fSDimitry Andric   }
1835f757f3fSDimitry Andric }
1845f757f3fSDimitry Andric 
1855f757f3fSDimitry Andric void fixupIndex(DWARFContext &C, DWARFUnitIndex &Index) {
1865f757f3fSDimitry Andric   if (Index.getVersion() < 5)
1875f757f3fSDimitry Andric     fixupIndexV4(C, Index);
1885f757f3fSDimitry Andric   else
1895f757f3fSDimitry Andric     fixupIndexV5(C, Index);
1905f757f3fSDimitry Andric }
1915f757f3fSDimitry Andric 
1925f757f3fSDimitry Andric template <typename T>
1935f757f3fSDimitry Andric static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
1945f757f3fSDimitry Andric                         const DWARFSection &Section, StringRef StringSection,
1955f757f3fSDimitry Andric                         bool IsLittleEndian) {
1965f757f3fSDimitry Andric   if (Cache)
1975f757f3fSDimitry Andric     return *Cache;
1985f757f3fSDimitry Andric   DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
1995f757f3fSDimitry Andric   DataExtractor StrData(StringSection, IsLittleEndian, 0);
2005f757f3fSDimitry Andric   Cache = std::make_unique<T>(AccelSection, StrData);
2015f757f3fSDimitry Andric   if (Error E = Cache->extract())
2025f757f3fSDimitry Andric     llvm::consumeError(std::move(E));
2035f757f3fSDimitry Andric   return *Cache;
2045f757f3fSDimitry Andric }
2055f757f3fSDimitry Andric 
2065f757f3fSDimitry Andric 
2075f757f3fSDimitry Andric std::unique_ptr<DWARFDebugMacro>
2085f757f3fSDimitry Andric DWARFContext::DWARFContextState::parseMacroOrMacinfo(MacroSecType SectionType) {
2095f757f3fSDimitry Andric   auto Macro = std::make_unique<DWARFDebugMacro>();
2105f757f3fSDimitry Andric   auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
2115f757f3fSDimitry Andric     if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
2125f757f3fSDimitry Andric                                                     ? D.compile_units()
2135f757f3fSDimitry Andric                                                     : D.dwo_compile_units(),
2145f757f3fSDimitry Andric                                                 SectionType == MacroSection
2155f757f3fSDimitry Andric                                                     ? D.getStringExtractor()
2165f757f3fSDimitry Andric                                                     : D.getStringDWOExtractor(),
2175f757f3fSDimitry Andric                                                 Data)
2185f757f3fSDimitry Andric                             : Macro->parseMacinfo(Data)) {
2195f757f3fSDimitry Andric       D.getRecoverableErrorHandler()(std::move(Err));
2205f757f3fSDimitry Andric       Macro = nullptr;
2215f757f3fSDimitry Andric     }
2225f757f3fSDimitry Andric   };
2235f757f3fSDimitry Andric   const DWARFObject &DObj = D.getDWARFObj();
2245f757f3fSDimitry Andric   switch (SectionType) {
2255f757f3fSDimitry Andric   case MacinfoSection: {
2265f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj.getMacinfoSection(), D.isLittleEndian(), 0);
2275f757f3fSDimitry Andric     ParseAndDump(Data, /*IsMacro=*/false);
2285f757f3fSDimitry Andric     break;
2295f757f3fSDimitry Andric   }
2305f757f3fSDimitry Andric   case MacinfoDwoSection: {
2315f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj.getMacinfoDWOSection(), D.isLittleEndian(), 0);
2325f757f3fSDimitry Andric     ParseAndDump(Data, /*IsMacro=*/false);
2335f757f3fSDimitry Andric     break;
2345f757f3fSDimitry Andric   }
2355f757f3fSDimitry Andric   case MacroSection: {
2365f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj, DObj.getMacroSection(), D.isLittleEndian(),
2375f757f3fSDimitry Andric                             0);
2385f757f3fSDimitry Andric     ParseAndDump(Data, /*IsMacro=*/true);
2395f757f3fSDimitry Andric     break;
2405f757f3fSDimitry Andric   }
2415f757f3fSDimitry Andric   case MacroDwoSection: {
2425f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj.getMacroDWOSection(), D.isLittleEndian(), 0);
2435f757f3fSDimitry Andric     ParseAndDump(Data, /*IsMacro=*/true);
2445f757f3fSDimitry Andric     break;
2455f757f3fSDimitry Andric   }
2465f757f3fSDimitry Andric   }
2475f757f3fSDimitry Andric   return Macro;
2485f757f3fSDimitry Andric }
2495f757f3fSDimitry Andric 
250*0fca6ea1SDimitry Andric namespace {
2515f757f3fSDimitry Andric class ThreadUnsafeDWARFContextState : public DWARFContext::DWARFContextState {
2525f757f3fSDimitry Andric 
2535f757f3fSDimitry Andric   DWARFUnitVector NormalUnits;
2545f757f3fSDimitry Andric   std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
2555f757f3fSDimitry Andric   std::unique_ptr<DWARFUnitIndex> CUIndex;
2565f757f3fSDimitry Andric   std::unique_ptr<DWARFGdbIndex> GdbIndex;
2575f757f3fSDimitry Andric   std::unique_ptr<DWARFUnitIndex> TUIndex;
2585f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
2595f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugLoc> Loc;
2605f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugAranges> Aranges;
2615f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugLine> Line;
2625f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugFrame> DebugFrame;
2635f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugFrame> EHFrame;
2645f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugMacro> Macro;
2655f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugMacro> Macinfo;
2665f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugNames> Names;
2675f757f3fSDimitry Andric   std::unique_ptr<AppleAcceleratorTable> AppleNames;
2685f757f3fSDimitry Andric   std::unique_ptr<AppleAcceleratorTable> AppleTypes;
2695f757f3fSDimitry Andric   std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
2705f757f3fSDimitry Andric   std::unique_ptr<AppleAcceleratorTable> AppleObjC;
2715f757f3fSDimitry Andric   DWARFUnitVector DWOUnits;
2725f757f3fSDimitry Andric   std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
2735f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
2745f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
2755f757f3fSDimitry Andric   std::unique_ptr<DWARFDebugMacro> MacroDWO;
2765f757f3fSDimitry Andric   struct DWOFile {
2775f757f3fSDimitry Andric     object::OwningBinary<object::ObjectFile> File;
2785f757f3fSDimitry Andric     std::unique_ptr<DWARFContext> Context;
2795f757f3fSDimitry Andric   };
2805f757f3fSDimitry Andric   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
2815f757f3fSDimitry Andric   std::weak_ptr<DWOFile> DWP;
2825f757f3fSDimitry Andric   bool CheckedForDWP = false;
2835f757f3fSDimitry Andric   std::string DWPName;
2845f757f3fSDimitry Andric 
2855f757f3fSDimitry Andric public:
2865f757f3fSDimitry Andric   ThreadUnsafeDWARFContextState(DWARFContext &DC, std::string &DWP) :
2875f757f3fSDimitry Andric       DWARFContext::DWARFContextState(DC),
2885f757f3fSDimitry Andric       DWPName(std::move(DWP)) {}
2895f757f3fSDimitry Andric 
2905f757f3fSDimitry Andric   DWARFUnitVector &getNormalUnits() override {
2915f757f3fSDimitry Andric     if (NormalUnits.empty()) {
2925f757f3fSDimitry Andric       const DWARFObject &DObj = D.getDWARFObj();
2935f757f3fSDimitry Andric       DObj.forEachInfoSections([&](const DWARFSection &S) {
2945f757f3fSDimitry Andric         NormalUnits.addUnitsForSection(D, S, DW_SECT_INFO);
2955f757f3fSDimitry Andric       });
2965f757f3fSDimitry Andric       NormalUnits.finishedInfoUnits();
2975f757f3fSDimitry Andric       DObj.forEachTypesSections([&](const DWARFSection &S) {
2985f757f3fSDimitry Andric         NormalUnits.addUnitsForSection(D, S, DW_SECT_EXT_TYPES);
2995f757f3fSDimitry Andric       });
3005f757f3fSDimitry Andric     }
3015f757f3fSDimitry Andric     return NormalUnits;
3025f757f3fSDimitry Andric   }
3035f757f3fSDimitry Andric 
3045f757f3fSDimitry Andric   DWARFUnitVector &getDWOUnits(bool Lazy) override {
3055f757f3fSDimitry Andric     if (DWOUnits.empty()) {
3065f757f3fSDimitry Andric       const DWARFObject &DObj = D.getDWARFObj();
3075f757f3fSDimitry Andric 
3085f757f3fSDimitry Andric       DObj.forEachInfoDWOSections([&](const DWARFSection &S) {
3095f757f3fSDimitry Andric         DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_INFO, Lazy);
3105f757f3fSDimitry Andric       });
3115f757f3fSDimitry Andric       DWOUnits.finishedInfoUnits();
3125f757f3fSDimitry Andric       DObj.forEachTypesDWOSections([&](const DWARFSection &S) {
3135f757f3fSDimitry Andric         DWOUnits.addUnitsForDWOSection(D, S, DW_SECT_EXT_TYPES, Lazy);
3145f757f3fSDimitry Andric       });
3155f757f3fSDimitry Andric     }
3165f757f3fSDimitry Andric     return DWOUnits;
3175f757f3fSDimitry Andric   }
3185f757f3fSDimitry Andric 
3195f757f3fSDimitry Andric   const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
3205f757f3fSDimitry Andric     if (AbbrevDWO)
3215f757f3fSDimitry Andric       return AbbrevDWO.get();
3225f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
3235f757f3fSDimitry Andric     DataExtractor abbrData(DObj.getAbbrevDWOSection(), D.isLittleEndian(), 0);
3245f757f3fSDimitry Andric     AbbrevDWO = std::make_unique<DWARFDebugAbbrev>(abbrData);
3255f757f3fSDimitry Andric     return AbbrevDWO.get();
3265f757f3fSDimitry Andric   }
3275f757f3fSDimitry Andric 
3285f757f3fSDimitry Andric   const DWARFUnitIndex &getCUIndex() override {
3295f757f3fSDimitry Andric     if (CUIndex)
3305f757f3fSDimitry Andric       return *CUIndex;
3315f757f3fSDimitry Andric 
3325f757f3fSDimitry Andric     DataExtractor Data(D.getDWARFObj().getCUIndexSection(),
3335f757f3fSDimitry Andric                        D.isLittleEndian(), 0);
3345f757f3fSDimitry Andric     CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
3355f757f3fSDimitry Andric     if (CUIndex->parse(Data))
3365f757f3fSDimitry Andric       fixupIndex(D, *CUIndex);
3375f757f3fSDimitry Andric     return *CUIndex;
3385f757f3fSDimitry Andric   }
3395f757f3fSDimitry Andric   const DWARFUnitIndex &getTUIndex() override {
3405f757f3fSDimitry Andric     if (TUIndex)
3415f757f3fSDimitry Andric       return *TUIndex;
3425f757f3fSDimitry Andric 
3435f757f3fSDimitry Andric     DataExtractor Data(D.getDWARFObj().getTUIndexSection(),
3445f757f3fSDimitry Andric                        D.isLittleEndian(), 0);
3455f757f3fSDimitry Andric     TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
3465f757f3fSDimitry Andric     bool isParseSuccessful = TUIndex->parse(Data);
3475f757f3fSDimitry Andric     // If we are parsing TU-index and for .debug_types section we don't need
3485f757f3fSDimitry Andric     // to do anything.
3495f757f3fSDimitry Andric     if (isParseSuccessful && TUIndex->getVersion() != 2)
3505f757f3fSDimitry Andric       fixupIndex(D, *TUIndex);
3515f757f3fSDimitry Andric     return *TUIndex;
3525f757f3fSDimitry Andric   }
3535f757f3fSDimitry Andric 
3545f757f3fSDimitry Andric   DWARFGdbIndex &getGdbIndex() override {
3555f757f3fSDimitry Andric     if (GdbIndex)
3565f757f3fSDimitry Andric       return *GdbIndex;
3575f757f3fSDimitry Andric 
3585f757f3fSDimitry Andric     DataExtractor Data(D.getDWARFObj().getGdbIndexSection(), true /*LE*/, 0);
3595f757f3fSDimitry Andric     GdbIndex = std::make_unique<DWARFGdbIndex>();
3605f757f3fSDimitry Andric     GdbIndex->parse(Data);
3615f757f3fSDimitry Andric     return *GdbIndex;
3625f757f3fSDimitry Andric   }
3635f757f3fSDimitry Andric 
3645f757f3fSDimitry Andric   const DWARFDebugAbbrev *getDebugAbbrev() override {
3655f757f3fSDimitry Andric     if (Abbrev)
3665f757f3fSDimitry Andric       return Abbrev.get();
3675f757f3fSDimitry Andric 
3685f757f3fSDimitry Andric     DataExtractor Data(D.getDWARFObj().getAbbrevSection(),
3695f757f3fSDimitry Andric                        D.isLittleEndian(), 0);
3705f757f3fSDimitry Andric     Abbrev = std::make_unique<DWARFDebugAbbrev>(Data);
3715f757f3fSDimitry Andric     return Abbrev.get();
3725f757f3fSDimitry Andric   }
3735f757f3fSDimitry Andric 
3745f757f3fSDimitry Andric   const DWARFDebugLoc *getDebugLoc() override {
3755f757f3fSDimitry Andric     if (Loc)
3765f757f3fSDimitry Andric       return Loc.get();
3775f757f3fSDimitry Andric 
3785f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
3795f757f3fSDimitry Andric     // Assume all units have the same address byte size.
3805f757f3fSDimitry Andric     auto Data =
3815f757f3fSDimitry Andric         D.getNumCompileUnits()
3825f757f3fSDimitry Andric             ? DWARFDataExtractor(DObj, DObj.getLocSection(), D.isLittleEndian(),
3835f757f3fSDimitry Andric                                  D.getUnitAtIndex(0)->getAddressByteSize())
3845f757f3fSDimitry Andric             : DWARFDataExtractor("", D.isLittleEndian(), 0);
3855f757f3fSDimitry Andric     Loc = std::make_unique<DWARFDebugLoc>(std::move(Data));
3865f757f3fSDimitry Andric     return Loc.get();
3875f757f3fSDimitry Andric   }
3885f757f3fSDimitry Andric 
3895f757f3fSDimitry Andric   const DWARFDebugAranges *getDebugAranges() override {
3905f757f3fSDimitry Andric     if (Aranges)
3915f757f3fSDimitry Andric       return Aranges.get();
3925f757f3fSDimitry Andric 
3935f757f3fSDimitry Andric     Aranges = std::make_unique<DWARFDebugAranges>();
3945f757f3fSDimitry Andric     Aranges->generate(&D);
3955f757f3fSDimitry Andric     return Aranges.get();
3965f757f3fSDimitry Andric   }
3975f757f3fSDimitry Andric 
3985f757f3fSDimitry Andric   Expected<const DWARFDebugLine::LineTable *>
3995f757f3fSDimitry Andric   getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
4005f757f3fSDimitry Andric     if (!Line)
4015f757f3fSDimitry Andric       Line = std::make_unique<DWARFDebugLine>();
4025f757f3fSDimitry Andric 
4035f757f3fSDimitry Andric     auto UnitDIE = U->getUnitDIE();
4045f757f3fSDimitry Andric     if (!UnitDIE)
4055f757f3fSDimitry Andric       return nullptr;
4065f757f3fSDimitry Andric 
4075f757f3fSDimitry Andric     auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
4085f757f3fSDimitry Andric     if (!Offset)
4095f757f3fSDimitry Andric       return nullptr; // No line table for this compile unit.
4105f757f3fSDimitry Andric 
4115f757f3fSDimitry Andric     uint64_t stmtOffset = *Offset + U->getLineTableOffset();
4125f757f3fSDimitry Andric     // See if the line table is cached.
4135f757f3fSDimitry Andric     if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
4145f757f3fSDimitry Andric       return lt;
4155f757f3fSDimitry Andric 
4165f757f3fSDimitry Andric     // Make sure the offset is good before we try to parse.
4175f757f3fSDimitry Andric     if (stmtOffset >= U->getLineSection().Data.size())
4185f757f3fSDimitry Andric       return nullptr;
4195f757f3fSDimitry Andric 
4205f757f3fSDimitry Andric     // We have to parse it first.
4215f757f3fSDimitry Andric     DWARFDataExtractor Data(U->getContext().getDWARFObj(), U->getLineSection(),
4225f757f3fSDimitry Andric                             U->isLittleEndian(), U->getAddressByteSize());
4235f757f3fSDimitry Andric     return Line->getOrParseLineTable(Data, stmtOffset, U->getContext(), U,
4245f757f3fSDimitry Andric                                      RecoverableErrorHandler);
4255f757f3fSDimitry Andric 
4265f757f3fSDimitry Andric   }
4275f757f3fSDimitry Andric 
4285f757f3fSDimitry Andric   void clearLineTableForUnit(DWARFUnit *U) override {
4295f757f3fSDimitry Andric     if (!Line)
4305f757f3fSDimitry Andric       return;
4315f757f3fSDimitry Andric 
4325f757f3fSDimitry Andric     auto UnitDIE = U->getUnitDIE();
4335f757f3fSDimitry Andric     if (!UnitDIE)
4345f757f3fSDimitry Andric       return;
4355f757f3fSDimitry Andric 
4365f757f3fSDimitry Andric     auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
4375f757f3fSDimitry Andric     if (!Offset)
4385f757f3fSDimitry Andric       return;
4395f757f3fSDimitry Andric 
4405f757f3fSDimitry Andric     uint64_t stmtOffset = *Offset + U->getLineTableOffset();
4415f757f3fSDimitry Andric     Line->clearLineTable(stmtOffset);
4425f757f3fSDimitry Andric   }
4435f757f3fSDimitry Andric 
4445f757f3fSDimitry Andric   Expected<const DWARFDebugFrame *> getDebugFrame() override {
4455f757f3fSDimitry Andric     if (DebugFrame)
4465f757f3fSDimitry Andric       return DebugFrame.get();
4475f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
4485f757f3fSDimitry Andric     const DWARFSection &DS = DObj.getFrameSection();
4495f757f3fSDimitry Andric 
4505f757f3fSDimitry Andric     // There's a "bug" in the DWARFv3 standard with respect to the target address
4515f757f3fSDimitry Andric     // size within debug frame sections. While DWARF is supposed to be independent
4525f757f3fSDimitry Andric     // of its container, FDEs have fields with size being "target address size",
4535f757f3fSDimitry Andric     // which isn't specified in DWARF in general. It's only specified for CUs, but
4545f757f3fSDimitry Andric     // .eh_frame can appear without a .debug_info section. Follow the example of
4555f757f3fSDimitry Andric     // other tools (libdwarf) and extract this from the container (ObjectFile
4565f757f3fSDimitry Andric     // provides this information). This problem is fixed in DWARFv4
4575f757f3fSDimitry Andric     // See this dwarf-discuss discussion for more details:
4585f757f3fSDimitry Andric     // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
4595f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
4605f757f3fSDimitry Andric                             DObj.getAddressSize());
4615f757f3fSDimitry Andric     auto DF =
4625f757f3fSDimitry Andric         std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/false,
4635f757f3fSDimitry Andric                                           DS.Address);
4645f757f3fSDimitry Andric     if (Error E = DF->parse(Data))
4655f757f3fSDimitry Andric       return std::move(E);
4665f757f3fSDimitry Andric 
4675f757f3fSDimitry Andric     DebugFrame.swap(DF);
4685f757f3fSDimitry Andric     return DebugFrame.get();
4695f757f3fSDimitry Andric   }
4705f757f3fSDimitry Andric 
4715f757f3fSDimitry Andric   Expected<const DWARFDebugFrame *> getEHFrame() override {
4725f757f3fSDimitry Andric     if (EHFrame)
4735f757f3fSDimitry Andric       return EHFrame.get();
4745f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
4755f757f3fSDimitry Andric 
4765f757f3fSDimitry Andric     const DWARFSection &DS = DObj.getEHFrameSection();
4775f757f3fSDimitry Andric     DWARFDataExtractor Data(DObj, DS, D.isLittleEndian(),
4785f757f3fSDimitry Andric                             DObj.getAddressSize());
4795f757f3fSDimitry Andric     auto DF =
4805f757f3fSDimitry Andric         std::make_unique<DWARFDebugFrame>(D.getArch(), /*IsEH=*/true,
4815f757f3fSDimitry Andric                                           DS.Address);
4825f757f3fSDimitry Andric     if (Error E = DF->parse(Data))
4835f757f3fSDimitry Andric       return std::move(E);
4845f757f3fSDimitry Andric     EHFrame.swap(DF);
4855f757f3fSDimitry Andric     return EHFrame.get();
4865f757f3fSDimitry Andric   }
4875f757f3fSDimitry Andric 
4885f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacinfo() override {
4895f757f3fSDimitry Andric     if (!Macinfo)
4905f757f3fSDimitry Andric       Macinfo = parseMacroOrMacinfo(MacinfoSection);
4915f757f3fSDimitry Andric     return Macinfo.get();
4925f757f3fSDimitry Andric   }
4935f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacinfoDWO() override {
4945f757f3fSDimitry Andric     if (!MacinfoDWO)
4955f757f3fSDimitry Andric       MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
4965f757f3fSDimitry Andric     return MacinfoDWO.get();
4975f757f3fSDimitry Andric   }
4985f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacro() override {
4995f757f3fSDimitry Andric     if (!Macro)
5005f757f3fSDimitry Andric       Macro = parseMacroOrMacinfo(MacroSection);
5015f757f3fSDimitry Andric     return Macro.get();
5025f757f3fSDimitry Andric   }
5035f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacroDWO() override {
5045f757f3fSDimitry Andric     if (!MacroDWO)
5055f757f3fSDimitry Andric       MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
5065f757f3fSDimitry Andric     return MacroDWO.get();
5075f757f3fSDimitry Andric   }
5085f757f3fSDimitry Andric   const DWARFDebugNames &getDebugNames() override {
5095f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5105f757f3fSDimitry Andric     return getAccelTable(Names, DObj, DObj.getNamesSection(),
5115f757f3fSDimitry Andric                          DObj.getStrSection(), D.isLittleEndian());
5125f757f3fSDimitry Andric   }
5135f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleNames() override {
5145f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5155f757f3fSDimitry Andric     return getAccelTable(AppleNames, DObj, DObj.getAppleNamesSection(),
5165f757f3fSDimitry Andric                          DObj.getStrSection(), D.isLittleEndian());
5175f757f3fSDimitry Andric 
5185f757f3fSDimitry Andric   }
5195f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleTypes() override {
5205f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5215f757f3fSDimitry Andric     return getAccelTable(AppleTypes, DObj, DObj.getAppleTypesSection(),
5225f757f3fSDimitry Andric                          DObj.getStrSection(), D.isLittleEndian());
5235f757f3fSDimitry Andric 
5245f757f3fSDimitry Andric   }
5255f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleNamespaces() override {
5265f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5275f757f3fSDimitry Andric     return getAccelTable(AppleNamespaces, DObj,
5285f757f3fSDimitry Andric                          DObj.getAppleNamespacesSection(),
5295f757f3fSDimitry Andric                          DObj.getStrSection(), D.isLittleEndian());
5305f757f3fSDimitry Andric 
5315f757f3fSDimitry Andric   }
5325f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleObjC() override {
5335f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5345f757f3fSDimitry Andric     return getAccelTable(AppleObjC, DObj, DObj.getAppleObjCSection(),
5355f757f3fSDimitry Andric                          DObj.getStrSection(), D.isLittleEndian());
5365f757f3fSDimitry Andric   }
5375f757f3fSDimitry Andric 
5385f757f3fSDimitry Andric   std::shared_ptr<DWARFContext>
5395f757f3fSDimitry Andric   getDWOContext(StringRef AbsolutePath) override {
5405f757f3fSDimitry Andric     if (auto S = DWP.lock()) {
5415f757f3fSDimitry Andric       DWARFContext *Ctxt = S->Context.get();
5425f757f3fSDimitry Andric       return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
5435f757f3fSDimitry Andric     }
5445f757f3fSDimitry Andric 
5455f757f3fSDimitry Andric     std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
5465f757f3fSDimitry Andric 
5475f757f3fSDimitry Andric     if (auto S = Entry->lock()) {
5485f757f3fSDimitry Andric       DWARFContext *Ctxt = S->Context.get();
5495f757f3fSDimitry Andric       return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
5505f757f3fSDimitry Andric     }
5515f757f3fSDimitry Andric 
5525f757f3fSDimitry Andric     const DWARFObject &DObj = D.getDWARFObj();
5535f757f3fSDimitry Andric 
5545f757f3fSDimitry Andric     Expected<OwningBinary<ObjectFile>> Obj = [&] {
5555f757f3fSDimitry Andric       if (!CheckedForDWP) {
5565f757f3fSDimitry Andric         SmallString<128> DWPName;
5575f757f3fSDimitry Andric         auto Obj = object::ObjectFile::createObjectFile(
5585f757f3fSDimitry Andric             this->DWPName.empty()
5595f757f3fSDimitry Andric                 ? (DObj.getFileName() + ".dwp").toStringRef(DWPName)
5605f757f3fSDimitry Andric                 : StringRef(this->DWPName));
5615f757f3fSDimitry Andric         if (Obj) {
5625f757f3fSDimitry Andric           Entry = &DWP;
5635f757f3fSDimitry Andric           return Obj;
5645f757f3fSDimitry Andric         } else {
5655f757f3fSDimitry Andric           CheckedForDWP = true;
5665f757f3fSDimitry Andric           // TODO: Should this error be handled (maybe in a high verbosity mode)
5675f757f3fSDimitry Andric           // before falling back to .dwo files?
5685f757f3fSDimitry Andric           consumeError(Obj.takeError());
5695f757f3fSDimitry Andric         }
5705f757f3fSDimitry Andric       }
5715f757f3fSDimitry Andric 
5725f757f3fSDimitry Andric       return object::ObjectFile::createObjectFile(AbsolutePath);
5735f757f3fSDimitry Andric     }();
5745f757f3fSDimitry Andric 
5755f757f3fSDimitry Andric     if (!Obj) {
5765f757f3fSDimitry Andric       // TODO: Actually report errors helpfully.
5775f757f3fSDimitry Andric       consumeError(Obj.takeError());
5785f757f3fSDimitry Andric       return nullptr;
5795f757f3fSDimitry Andric     }
5805f757f3fSDimitry Andric 
5815f757f3fSDimitry Andric     auto S = std::make_shared<DWOFile>();
5825f757f3fSDimitry Andric     S->File = std::move(Obj.get());
5835f757f3fSDimitry Andric     // Allow multi-threaded access if there is a .dwp file as the CU index and
5845f757f3fSDimitry Andric     // TU index might be accessed from multiple threads.
5855f757f3fSDimitry Andric     bool ThreadSafe = isThreadSafe();
5865f757f3fSDimitry Andric     S->Context = DWARFContext::create(
5875f757f3fSDimitry Andric         *S->File.getBinary(), DWARFContext::ProcessDebugRelocations::Ignore,
5885f757f3fSDimitry Andric         nullptr, "", WithColor::defaultErrorHandler,
5895f757f3fSDimitry Andric         WithColor::defaultWarningHandler, ThreadSafe);
5905f757f3fSDimitry Andric     *Entry = S;
5915f757f3fSDimitry Andric     auto *Ctxt = S->Context.get();
5925f757f3fSDimitry Andric     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
5935f757f3fSDimitry Andric   }
5945f757f3fSDimitry Andric 
5955f757f3fSDimitry Andric   bool isThreadSafe() const override { return false; }
5965f757f3fSDimitry Andric 
5975f757f3fSDimitry Andric   const DenseMap<uint64_t, DWARFTypeUnit *> &getNormalTypeUnitMap() {
5985f757f3fSDimitry Andric     if (!NormalTypeUnits) {
5995f757f3fSDimitry Andric       NormalTypeUnits.emplace();
6005f757f3fSDimitry Andric       for (const auto &U :D.normal_units()) {
6015f757f3fSDimitry Andric         if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
6025f757f3fSDimitry Andric           (*NormalTypeUnits)[TU->getTypeHash()] = TU;
6035f757f3fSDimitry Andric       }
6045f757f3fSDimitry Andric     }
6055f757f3fSDimitry Andric     return *NormalTypeUnits;
6065f757f3fSDimitry Andric   }
6075f757f3fSDimitry Andric 
6085f757f3fSDimitry Andric   const DenseMap<uint64_t, DWARFTypeUnit *> &getDWOTypeUnitMap() {
6095f757f3fSDimitry Andric     if (!DWOTypeUnits) {
6105f757f3fSDimitry Andric       DWOTypeUnits.emplace();
6115f757f3fSDimitry Andric       for (const auto &U :D.dwo_units()) {
6125f757f3fSDimitry Andric         if (DWARFTypeUnit *TU = dyn_cast<DWARFTypeUnit>(U.get()))
6135f757f3fSDimitry Andric           (*DWOTypeUnits)[TU->getTypeHash()] = TU;
6145f757f3fSDimitry Andric       }
6155f757f3fSDimitry Andric     }
6165f757f3fSDimitry Andric     return *DWOTypeUnits;
6175f757f3fSDimitry Andric   }
6185f757f3fSDimitry Andric 
6195f757f3fSDimitry Andric   const DenseMap<uint64_t, DWARFTypeUnit *> &
6205f757f3fSDimitry Andric   getTypeUnitMap(bool IsDWO) override {
6215f757f3fSDimitry Andric     if (IsDWO)
6225f757f3fSDimitry Andric       return getDWOTypeUnitMap();
6235f757f3fSDimitry Andric     else
6245f757f3fSDimitry Andric       return getNormalTypeUnitMap();
6255f757f3fSDimitry Andric   }
6265f757f3fSDimitry Andric 
6275f757f3fSDimitry Andric 
6285f757f3fSDimitry Andric };
6295f757f3fSDimitry Andric 
6305f757f3fSDimitry Andric class ThreadSafeState : public ThreadUnsafeDWARFContextState {
6315f757f3fSDimitry Andric   std::recursive_mutex Mutex;
6325f757f3fSDimitry Andric 
6335f757f3fSDimitry Andric public:
6345f757f3fSDimitry Andric   ThreadSafeState(DWARFContext &DC, std::string &DWP) :
6355f757f3fSDimitry Andric       ThreadUnsafeDWARFContextState(DC, DWP) {}
6365f757f3fSDimitry Andric 
6375f757f3fSDimitry Andric   DWARFUnitVector &getNormalUnits() override {
6385f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6395f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getNormalUnits();
6405f757f3fSDimitry Andric   }
6415f757f3fSDimitry Andric   DWARFUnitVector &getDWOUnits(bool Lazy) override {
6425f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6435f757f3fSDimitry Andric     // We need to not do lazy parsing when we need thread safety as
6445f757f3fSDimitry Andric     // DWARFUnitVector, in lazy mode, will slowly add things to itself and
6455f757f3fSDimitry Andric     // will cause problems in a multi-threaded environment.
6465f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDWOUnits(false);
6475f757f3fSDimitry Andric   }
6485f757f3fSDimitry Andric   const DWARFUnitIndex &getCUIndex() override {
6495f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6505f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getCUIndex();
6515f757f3fSDimitry Andric   }
6525f757f3fSDimitry Andric   const DWARFDebugAbbrev *getDebugAbbrevDWO() override {
6535f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6545f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugAbbrevDWO();
6555f757f3fSDimitry Andric   }
6565f757f3fSDimitry Andric 
6575f757f3fSDimitry Andric   const DWARFUnitIndex &getTUIndex() override {
6585f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6595f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getTUIndex();
6605f757f3fSDimitry Andric   }
6615f757f3fSDimitry Andric   DWARFGdbIndex &getGdbIndex() override {
6625f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6635f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getGdbIndex();
6645f757f3fSDimitry Andric   }
6655f757f3fSDimitry Andric   const DWARFDebugAbbrev *getDebugAbbrev() override {
6665f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6675f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugAbbrev();
6685f757f3fSDimitry Andric   }
6695f757f3fSDimitry Andric   const DWARFDebugLoc *getDebugLoc() override {
6705f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6715f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugLoc();
6725f757f3fSDimitry Andric   }
6735f757f3fSDimitry Andric   const DWARFDebugAranges *getDebugAranges() override {
6745f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6755f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugAranges();
6765f757f3fSDimitry Andric   }
6775f757f3fSDimitry Andric   Expected<const DWARFDebugLine::LineTable *>
6785f757f3fSDimitry Andric   getLineTableForUnit(DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) override {
6795f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6805f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getLineTableForUnit(U, RecoverableErrorHandler);
6815f757f3fSDimitry Andric   }
6825f757f3fSDimitry Andric   void clearLineTableForUnit(DWARFUnit *U) override {
6835f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6845f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::clearLineTableForUnit(U);
6855f757f3fSDimitry Andric   }
6865f757f3fSDimitry Andric   Expected<const DWARFDebugFrame *> getDebugFrame() override {
6875f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6885f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugFrame();
6895f757f3fSDimitry Andric   }
6905f757f3fSDimitry Andric   Expected<const DWARFDebugFrame *> getEHFrame() override {
6915f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6925f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getEHFrame();
6935f757f3fSDimitry Andric   }
6945f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacinfo() override {
6955f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
6965f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugMacinfo();
6975f757f3fSDimitry Andric   }
6985f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacinfoDWO() override {
6995f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7005f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugMacinfoDWO();
7015f757f3fSDimitry Andric   }
7025f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacro() override {
7035f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7045f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugMacro();
7055f757f3fSDimitry Andric   }
7065f757f3fSDimitry Andric   const DWARFDebugMacro *getDebugMacroDWO() override {
7075f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7085f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugMacroDWO();
7095f757f3fSDimitry Andric   }
7105f757f3fSDimitry Andric   const DWARFDebugNames &getDebugNames() override {
7115f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7125f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDebugNames();
7135f757f3fSDimitry Andric   }
7145f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleNames() override {
7155f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7165f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getAppleNames();
7175f757f3fSDimitry Andric   }
7185f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleTypes() override {
7195f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7205f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getAppleTypes();
7215f757f3fSDimitry Andric   }
7225f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleNamespaces() override {
7235f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7245f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getAppleNamespaces();
7255f757f3fSDimitry Andric   }
7265f757f3fSDimitry Andric   const AppleAcceleratorTable &getAppleObjC() override {
7275f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7285f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getAppleObjC();
7295f757f3fSDimitry Andric   }
7305f757f3fSDimitry Andric   std::shared_ptr<DWARFContext>
7315f757f3fSDimitry Andric   getDWOContext(StringRef AbsolutePath) override {
7325f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7335f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getDWOContext(AbsolutePath);
7345f757f3fSDimitry Andric   }
7355f757f3fSDimitry Andric 
7365f757f3fSDimitry Andric   bool isThreadSafe() const override { return true; }
7375f757f3fSDimitry Andric 
7385f757f3fSDimitry Andric   const DenseMap<uint64_t, DWARFTypeUnit *> &
7395f757f3fSDimitry Andric   getTypeUnitMap(bool IsDWO) override {
7405f757f3fSDimitry Andric     std::unique_lock<std::recursive_mutex> LockGuard(Mutex);
7415f757f3fSDimitry Andric     return ThreadUnsafeDWARFContextState::getTypeUnitMap(IsDWO);
7425f757f3fSDimitry Andric   }
7435f757f3fSDimitry Andric };
744*0fca6ea1SDimitry Andric } // namespace
7455f757f3fSDimitry Andric 
7460b57cec5SDimitry Andric DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
7475ffd83dbSDimitry Andric                            std::string DWPName,
7485ffd83dbSDimitry Andric                            std::function<void(Error)> RecoverableErrorHandler,
7495f757f3fSDimitry Andric                            std::function<void(Error)> WarningHandler,
7505f757f3fSDimitry Andric                            bool ThreadSafe)
7515f757f3fSDimitry Andric     : DIContext(CK_DWARF),
7525ffd83dbSDimitry Andric       RecoverableErrorHandler(RecoverableErrorHandler),
7535f757f3fSDimitry Andric       WarningHandler(WarningHandler), DObj(std::move(DObj)) {
7545f757f3fSDimitry Andric         if (ThreadSafe)
7555f757f3fSDimitry Andric           State = std::make_unique<ThreadSafeState>(*this, DWPName);
7565f757f3fSDimitry Andric         else
7575f757f3fSDimitry Andric           State = std::make_unique<ThreadUnsafeDWARFContextState>(*this, DWPName);
7585f757f3fSDimitry Andric       }
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric DWARFContext::~DWARFContext() = default;
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric /// Dump the UUID load command.
7630b57cec5SDimitry Andric static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
7640b57cec5SDimitry Andric   auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
7650b57cec5SDimitry Andric   if (!MachO)
7660b57cec5SDimitry Andric     return;
7670b57cec5SDimitry Andric   for (auto LC : MachO->load_commands()) {
7680b57cec5SDimitry Andric     raw_ostream::uuid_t UUID;
7690b57cec5SDimitry Andric     if (LC.C.cmd == MachO::LC_UUID) {
7700b57cec5SDimitry Andric       if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
7710b57cec5SDimitry Andric         OS << "error: UUID load command is too short.\n";
7720b57cec5SDimitry Andric         return;
7730b57cec5SDimitry Andric       }
7740b57cec5SDimitry Andric       OS << "UUID: ";
7750b57cec5SDimitry Andric       memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
7760b57cec5SDimitry Andric       OS.write_uuid(UUID);
7770b57cec5SDimitry Andric       Triple T = MachO->getArchTriple();
7780b57cec5SDimitry Andric       OS << " (" << T.getArchName() << ')';
7790b57cec5SDimitry Andric       OS << ' ' << MachO->getFileName() << '\n';
7800b57cec5SDimitry Andric     }
7810b57cec5SDimitry Andric   }
7820b57cec5SDimitry Andric }
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric using ContributionCollection =
785bdd1243dSDimitry Andric     std::vector<std::optional<StrOffsetsContributionDescriptor>>;
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric // Collect all the contributions to the string offsets table from all units,
7880b57cec5SDimitry Andric // sort them by their starting offsets and remove duplicates.
7890b57cec5SDimitry Andric static ContributionCollection
7900b57cec5SDimitry Andric collectContributionData(DWARFContext::unit_iterator_range Units) {
7910b57cec5SDimitry Andric   ContributionCollection Contributions;
7920b57cec5SDimitry Andric   for (const auto &U : Units)
7930b57cec5SDimitry Andric     if (const auto &C = U->getStringOffsetsTableContribution())
7940b57cec5SDimitry Andric       Contributions.push_back(C);
7950b57cec5SDimitry Andric   // Sort the contributions so that any invalid ones are placed at
7960b57cec5SDimitry Andric   // the start of the contributions vector. This way they are reported
7970b57cec5SDimitry Andric   // first.
7980b57cec5SDimitry Andric   llvm::sort(Contributions,
799bdd1243dSDimitry Andric              [](const std::optional<StrOffsetsContributionDescriptor> &L,
800bdd1243dSDimitry Andric                 const std::optional<StrOffsetsContributionDescriptor> &R) {
8010b57cec5SDimitry Andric                if (L && R)
8020b57cec5SDimitry Andric                  return L->Base < R->Base;
80381ad6265SDimitry Andric                return R.has_value();
8040b57cec5SDimitry Andric              });
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   // Uniquify contributions, as it is possible that units (specifically
8070b57cec5SDimitry Andric   // type units in dwo or dwp files) share contributions. We don't want
8080b57cec5SDimitry Andric   // to report them more than once.
8090b57cec5SDimitry Andric   Contributions.erase(
810*0fca6ea1SDimitry Andric       llvm::unique(
811*0fca6ea1SDimitry Andric           Contributions,
812bdd1243dSDimitry Andric           [](const std::optional<StrOffsetsContributionDescriptor> &L,
813bdd1243dSDimitry Andric              const std::optional<StrOffsetsContributionDescriptor> &R) {
8140b57cec5SDimitry Andric             if (L && R)
8150b57cec5SDimitry Andric               return L->Base == R->Base && L->Size == R->Size;
8160b57cec5SDimitry Andric             return false;
8170b57cec5SDimitry Andric           }),
8180b57cec5SDimitry Andric       Contributions.end());
8190b57cec5SDimitry Andric   return Contributions;
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric 
8225ffd83dbSDimitry Andric // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
8235ffd83dbSDimitry Andric // string offsets section, where each compile or type unit contributes a
8245ffd83dbSDimitry Andric // number of entries (string offsets), with each contribution preceded by
8255ffd83dbSDimitry Andric // a header containing size and version number. Alternatively, it may be a
8265ffd83dbSDimitry Andric // monolithic series of string offsets, as generated by the pre-DWARF v5
8275ffd83dbSDimitry Andric // implementation of split DWARF; however, in that case we still need to
8285ffd83dbSDimitry Andric // collect contributions of units because the size of the offsets (4 or 8
8295ffd83dbSDimitry Andric // bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
8305ffd83dbSDimitry Andric static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
8315ffd83dbSDimitry Andric                                      StringRef SectionName,
8325ffd83dbSDimitry Andric                                      const DWARFObject &Obj,
8335ffd83dbSDimitry Andric                                      const DWARFSection &StringOffsetsSection,
8345ffd83dbSDimitry Andric                                      StringRef StringSection,
8355ffd83dbSDimitry Andric                                      DWARFContext::unit_iterator_range Units,
8365ffd83dbSDimitry Andric                                      bool LittleEndian) {
8370b57cec5SDimitry Andric   auto Contributions = collectContributionData(Units);
8380b57cec5SDimitry Andric   DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
8390b57cec5SDimitry Andric   DataExtractor StrData(StringSection, LittleEndian, 0);
8400b57cec5SDimitry Andric   uint64_t SectionSize = StringOffsetsSection.Data.size();
8418bcb0991SDimitry Andric   uint64_t Offset = 0;
8420b57cec5SDimitry Andric   for (auto &Contribution : Contributions) {
8430b57cec5SDimitry Andric     // Report an ill-formed contribution.
8440b57cec5SDimitry Andric     if (!Contribution) {
8450b57cec5SDimitry Andric       OS << "error: invalid contribution to string offsets table in section ."
8460b57cec5SDimitry Andric          << SectionName << ".\n";
8470b57cec5SDimitry Andric       return;
8480b57cec5SDimitry Andric     }
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric     dwarf::DwarfFormat Format = Contribution->getFormat();
8515ffd83dbSDimitry Andric     int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
8520b57cec5SDimitry Andric     uint16_t Version = Contribution->getVersion();
8530b57cec5SDimitry Andric     uint64_t ContributionHeader = Contribution->Base;
8540b57cec5SDimitry Andric     // In DWARF v5 there is a contribution header that immediately precedes
8550b57cec5SDimitry Andric     // the string offsets base (the location we have previously retrieved from
8560b57cec5SDimitry Andric     // the CU DIE's DW_AT_str_offsets attribute). The header is located either
8570b57cec5SDimitry Andric     // 8 or 16 bytes before the base, depending on the contribution's format.
8580b57cec5SDimitry Andric     if (Version >= 5)
8590b57cec5SDimitry Andric       ContributionHeader -= Format == DWARF32 ? 8 : 16;
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric     // Detect overlapping contributions.
8620b57cec5SDimitry Andric     if (Offset > ContributionHeader) {
8635ffd83dbSDimitry Andric       DumpOpts.RecoverableErrorHandler(createStringError(
8645ffd83dbSDimitry Andric           errc::invalid_argument,
8655ffd83dbSDimitry Andric           "overlapping contributions to string offsets table in section .%s.",
8665ffd83dbSDimitry Andric           SectionName.data()));
8670b57cec5SDimitry Andric     }
8680b57cec5SDimitry Andric     // Report a gap in the table.
8690b57cec5SDimitry Andric     if (Offset < ContributionHeader) {
8708bcb0991SDimitry Andric       OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
8710b57cec5SDimitry Andric       OS << (ContributionHeader - Offset) << "\n";
8720b57cec5SDimitry Andric     }
8738bcb0991SDimitry Andric     OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
8740b57cec5SDimitry Andric     // In DWARF v5 the contribution size in the descriptor does not equal
8750b57cec5SDimitry Andric     // the originally encoded length (it does not contain the length of the
8760b57cec5SDimitry Andric     // version field and the padding, a total of 4 bytes). Add them back in
8770b57cec5SDimitry Andric     // for reporting.
8780b57cec5SDimitry Andric     OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
8795ffd83dbSDimitry Andric        << ", Format = " << dwarf::FormatString(Format)
8800b57cec5SDimitry Andric        << ", Version = " << Version << "\n";
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric     Offset = Contribution->Base;
8830b57cec5SDimitry Andric     unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
8840b57cec5SDimitry Andric     while (Offset - Contribution->Base < Contribution->Size) {
8858bcb0991SDimitry Andric       OS << format("0x%8.8" PRIx64 ": ", Offset);
8860b57cec5SDimitry Andric       uint64_t StringOffset =
8870b57cec5SDimitry Andric           StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
8885ffd83dbSDimitry Andric       OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
8898bcb0991SDimitry Andric       const char *S = StrData.getCStr(&StringOffset);
8900b57cec5SDimitry Andric       if (S)
8910b57cec5SDimitry Andric         OS << format("\"%s\"", S);
8920b57cec5SDimitry Andric       OS << "\n";
8930b57cec5SDimitry Andric     }
8940b57cec5SDimitry Andric   }
8950b57cec5SDimitry Andric   // Report a gap at the end of the table.
8960b57cec5SDimitry Andric   if (Offset < SectionSize) {
8978bcb0991SDimitry Andric     OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
8980b57cec5SDimitry Andric     OS << (SectionSize - Offset) << "\n";
8990b57cec5SDimitry Andric   }
9000b57cec5SDimitry Andric }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric // Dump the .debug_addr section.
9030b57cec5SDimitry Andric static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
9040b57cec5SDimitry Andric                             DIDumpOptions DumpOpts, uint16_t Version,
9050b57cec5SDimitry Andric                             uint8_t AddrSize) {
9068bcb0991SDimitry Andric   uint64_t Offset = 0;
9070b57cec5SDimitry Andric   while (AddrData.isValidOffset(Offset)) {
9080b57cec5SDimitry Andric     DWARFDebugAddrTable AddrTable;
9098bcb0991SDimitry Andric     uint64_t TableOffset = Offset;
9100b57cec5SDimitry Andric     if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
9115ffd83dbSDimitry Andric                                       DumpOpts.WarningHandler)) {
9125ffd83dbSDimitry Andric       DumpOpts.RecoverableErrorHandler(std::move(Err));
9130b57cec5SDimitry Andric       // Keep going after an error, if we can, assuming that the length field
9140b57cec5SDimitry Andric       // could be read. If it couldn't, stop reading the section.
9155ffd83dbSDimitry Andric       if (auto TableLength = AddrTable.getFullLength()) {
9165ffd83dbSDimitry Andric         Offset = TableOffset + *TableLength;
9175ffd83dbSDimitry Andric         continue;
9180b57cec5SDimitry Andric       }
9195ffd83dbSDimitry Andric       break;
9205ffd83dbSDimitry Andric     }
9215ffd83dbSDimitry Andric     AddrTable.dump(OS, DumpOpts);
9220b57cec5SDimitry Andric   }
9230b57cec5SDimitry Andric }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
9260b57cec5SDimitry Andric static void dumpRnglistsSection(
9270b57cec5SDimitry Andric     raw_ostream &OS, DWARFDataExtractor &rnglistData,
928bdd1243dSDimitry Andric     llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)>
9290b57cec5SDimitry Andric         LookupPooledAddress,
9300b57cec5SDimitry Andric     DIDumpOptions DumpOpts) {
9318bcb0991SDimitry Andric   uint64_t Offset = 0;
9320b57cec5SDimitry Andric   while (rnglistData.isValidOffset(Offset)) {
9330b57cec5SDimitry Andric     llvm::DWARFDebugRnglistTable Rnglists;
9348bcb0991SDimitry Andric     uint64_t TableOffset = Offset;
9350b57cec5SDimitry Andric     if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
9365ffd83dbSDimitry Andric       DumpOpts.RecoverableErrorHandler(std::move(Err));
9370b57cec5SDimitry Andric       uint64_t Length = Rnglists.length();
9380b57cec5SDimitry Andric       // Keep going after an error, if we can, assuming that the length field
9390b57cec5SDimitry Andric       // could be read. If it couldn't, stop reading the section.
9400b57cec5SDimitry Andric       if (Length == 0)
9410b57cec5SDimitry Andric         break;
9420b57cec5SDimitry Andric       Offset = TableOffset + Length;
9430b57cec5SDimitry Andric     } else {
944e8d8bef9SDimitry Andric       Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
9450b57cec5SDimitry Andric     }
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
9495ffd83dbSDimitry Andric 
9500b57cec5SDimitry Andric static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
951bdd1243dSDimitry Andric                                 DWARFDataExtractor Data, const DWARFObject &Obj,
952bdd1243dSDimitry Andric                                 std::optional<uint64_t> DumpOffset) {
9538bcb0991SDimitry Andric   uint64_t Offset = 0;
9540b57cec5SDimitry Andric 
9558bcb0991SDimitry Andric   while (Data.isValidOffset(Offset)) {
9560b57cec5SDimitry Andric     DWARFListTableHeader Header(".debug_loclists", "locations");
9570b57cec5SDimitry Andric     if (Error E = Header.extract(Data, &Offset)) {
9585ffd83dbSDimitry Andric       DumpOpts.RecoverableErrorHandler(std::move(E));
9590b57cec5SDimitry Andric       return;
9600b57cec5SDimitry Andric     }
9610b57cec5SDimitry Andric 
962e8d8bef9SDimitry Andric     Header.dump(Data, OS, DumpOpts);
9630b57cec5SDimitry Andric 
9648bcb0991SDimitry Andric     uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
965480093f4SDimitry Andric     Data.setAddressSize(Header.getAddrSize());
966480093f4SDimitry Andric     DWARFDebugLoclists Loc(Data, Header.getVersion());
967480093f4SDimitry Andric     if (DumpOffset) {
968480093f4SDimitry Andric       if (DumpOffset >= Offset && DumpOffset < EndOffset) {
969480093f4SDimitry Andric         Offset = *DumpOffset;
970bdd1243dSDimitry Andric         Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj,
971bdd1243dSDimitry Andric                              nullptr, DumpOpts, /*Indent=*/0);
972480093f4SDimitry Andric         OS << "\n";
973480093f4SDimitry Andric         return;
974480093f4SDimitry Andric       }
975480093f4SDimitry Andric     } else {
976bdd1243dSDimitry Andric       Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts);
977480093f4SDimitry Andric     }
9788bcb0991SDimitry Andric     Offset = EndOffset;
9798bcb0991SDimitry Andric   }
9800b57cec5SDimitry Andric }
9810b57cec5SDimitry Andric 
9825ffd83dbSDimitry Andric static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts,
9835ffd83dbSDimitry Andric                                 DWARFDataExtractor Data, bool GnuStyle) {
9845ffd83dbSDimitry Andric   DWARFDebugPubTable Table;
9855ffd83dbSDimitry Andric   Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
9865ffd83dbSDimitry Andric   Table.dump(OS);
9875ffd83dbSDimitry Andric }
9885ffd83dbSDimitry Andric 
9890b57cec5SDimitry Andric void DWARFContext::dump(
9900b57cec5SDimitry Andric     raw_ostream &OS, DIDumpOptions DumpOpts,
991bdd1243dSDimitry Andric     std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
9920b57cec5SDimitry Andric   uint64_t DumpType = DumpOpts.DumpType;
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric   StringRef Extension = sys::path::extension(DObj->getFileName());
9950b57cec5SDimitry Andric   bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric   // Print UUID header.
9980b57cec5SDimitry Andric   const auto *ObjFile = DObj->getFile();
9990b57cec5SDimitry Andric   if (DumpType & DIDT_UUID)
10000b57cec5SDimitry Andric     dumpUUID(OS, *ObjFile);
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   // Print a header for each explicitly-requested section.
10030b57cec5SDimitry Andric   // Otherwise just print one for non-empty sections.
10040b57cec5SDimitry Andric   // Only print empty .dwo section headers when dumping a .dwo file.
10050b57cec5SDimitry Andric   bool Explicit = DumpType != DIDT_All && !IsDWO;
10060b57cec5SDimitry Andric   bool ExplicitDWO = Explicit && IsDWO;
10070b57cec5SDimitry Andric   auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
1008bdd1243dSDimitry Andric                         StringRef Section) -> std::optional<uint64_t> * {
10090b57cec5SDimitry Andric     unsigned Mask = 1U << ID;
10100b57cec5SDimitry Andric     bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
10110b57cec5SDimitry Andric     if (!Should)
10120b57cec5SDimitry Andric       return nullptr;
10130b57cec5SDimitry Andric     OS << "\n" << Name << " contents:\n";
10140b57cec5SDimitry Andric     return &DumpOffsets[ID];
10150b57cec5SDimitry Andric   };
10160b57cec5SDimitry Andric 
10170b57cec5SDimitry Andric   // Dump individual sections.
10180b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
10190b57cec5SDimitry Andric                  DObj->getAbbrevSection()))
10200b57cec5SDimitry Andric     getDebugAbbrev()->dump(OS);
10210b57cec5SDimitry Andric   if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
10220b57cec5SDimitry Andric                  DObj->getAbbrevDWOSection()))
10230b57cec5SDimitry Andric     getDebugAbbrevDWO()->dump(OS);
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric   auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
10260b57cec5SDimitry Andric     OS << '\n' << Name << " contents:\n";
10270b57cec5SDimitry Andric     if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
10287a6dacacSDimitry Andric       for (const auto &U : Units) {
102981ad6265SDimitry Andric         U->getDIEForOffset(*DumpOffset)
10300b57cec5SDimitry Andric             .dump(OS, 0, DumpOpts.noImplicitRecursion());
10317a6dacacSDimitry Andric         DWARFDie CUDie = U->getUnitDIE(false);
10327a6dacacSDimitry Andric         DWARFDie CUNonSkeletonDie = U->getNonSkeletonUnitDIE(false);
10337a6dacacSDimitry Andric         if (CUNonSkeletonDie && CUDie != CUNonSkeletonDie) {
10347a6dacacSDimitry Andric           CUNonSkeletonDie.getDwarfUnit()
10357a6dacacSDimitry Andric               ->getDIEForOffset(*DumpOffset)
10367a6dacacSDimitry Andric               .dump(OS, 0, DumpOpts.noImplicitRecursion());
10377a6dacacSDimitry Andric         }
10387a6dacacSDimitry Andric       }
10390b57cec5SDimitry Andric     else
10400b57cec5SDimitry Andric       for (const auto &U : Units)
10410b57cec5SDimitry Andric         U->dump(OS, DumpOpts);
10420b57cec5SDimitry Andric   };
10430b57cec5SDimitry Andric   if ((DumpType & DIDT_DebugInfo)) {
10440b57cec5SDimitry Andric     if (Explicit || getNumCompileUnits())
10450b57cec5SDimitry Andric       dumpDebugInfo(".debug_info", info_section_units());
10460b57cec5SDimitry Andric     if (ExplicitDWO || getNumDWOCompileUnits())
10470b57cec5SDimitry Andric       dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
10480b57cec5SDimitry Andric   }
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
10510b57cec5SDimitry Andric     OS << '\n' << Name << " contents:\n";
10520b57cec5SDimitry Andric     for (const auto &U : Units)
10530b57cec5SDimitry Andric       if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
10540b57cec5SDimitry Andric         U->getDIEForOffset(*DumpOffset)
10550b57cec5SDimitry Andric             .dump(OS, 0, DumpOpts.noImplicitRecursion());
10560b57cec5SDimitry Andric       else
10570b57cec5SDimitry Andric         U->dump(OS, DumpOpts);
10580b57cec5SDimitry Andric   };
10590b57cec5SDimitry Andric   if ((DumpType & DIDT_DebugTypes)) {
10600b57cec5SDimitry Andric     if (Explicit || getNumTypeUnits())
10610b57cec5SDimitry Andric       dumpDebugType(".debug_types", types_section_units());
10620b57cec5SDimitry Andric     if (ExplicitDWO || getNumDWOTypeUnits())
10630b57cec5SDimitry Andric       dumpDebugType(".debug_types.dwo", dwo_types_section_units());
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric 
1066480093f4SDimitry Andric   DIDumpOptions LLDumpOpts = DumpOpts;
1067480093f4SDimitry Andric   if (LLDumpOpts.Verbose)
1068480093f4SDimitry Andric     LLDumpOpts.DisplayRawContents = true;
1069480093f4SDimitry Andric 
10700b57cec5SDimitry Andric   if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
10710b57cec5SDimitry Andric                                    DObj->getLocSection().Data)) {
1072bdd1243dSDimitry Andric     getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off);
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric   if (const auto *Off =
10750b57cec5SDimitry Andric           shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
10760b57cec5SDimitry Andric                      DObj->getLoclistsSection().Data)) {
10770b57cec5SDimitry Andric     DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
10780b57cec5SDimitry Andric                             0);
1079bdd1243dSDimitry Andric     dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
10800b57cec5SDimitry Andric   }
10810b57cec5SDimitry Andric   if (const auto *Off =
1082480093f4SDimitry Andric           shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
1083480093f4SDimitry Andric                      DObj->getLoclistsDWOSection().Data)) {
1084480093f4SDimitry Andric     DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
1085480093f4SDimitry Andric                             isLittleEndian(), 0);
1086bdd1243dSDimitry Andric     dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off);
1087480093f4SDimitry Andric   }
1088480093f4SDimitry Andric 
1089480093f4SDimitry Andric   if (const auto *Off =
10900b57cec5SDimitry Andric           shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
10910b57cec5SDimitry Andric                      DObj->getLocDWOSection().Data)) {
1092480093f4SDimitry Andric     DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
1093480093f4SDimitry Andric                             4);
1094480093f4SDimitry Andric     DWARFDebugLoclists Loc(Data, /*Version=*/4);
1095480093f4SDimitry Andric     if (*Off) {
1096480093f4SDimitry Andric       uint64_t Offset = **Off;
1097480093f4SDimitry Andric       Loc.dumpLocationList(&Offset, OS,
1098bdd1243dSDimitry Andric                            /*BaseAddr=*/std::nullopt, *DObj, nullptr,
1099bdd1243dSDimitry Andric                            LLDumpOpts,
1100bdd1243dSDimitry Andric                            /*Indent=*/0);
1101480093f4SDimitry Andric       OS << "\n";
1102480093f4SDimitry Andric     } else {
1103bdd1243dSDimitry Andric       Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts);
1104480093f4SDimitry Andric     }
11050b57cec5SDimitry Andric   }
11060b57cec5SDimitry Andric 
1107bdd1243dSDimitry Andric   if (const std::optional<uint64_t> *Off =
11085ffd83dbSDimitry Andric           shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
11095ffd83dbSDimitry Andric                      DObj->getFrameSection().Data)) {
11105ffd83dbSDimitry Andric     if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
1111bdd1243dSDimitry Andric       (*DF)->dump(OS, DumpOpts, *Off);
11125ffd83dbSDimitry Andric     else
11135ffd83dbSDimitry Andric       RecoverableErrorHandler(DF.takeError());
11140b57cec5SDimitry Andric   }
11155ffd83dbSDimitry Andric 
1116bdd1243dSDimitry Andric   if (const std::optional<uint64_t> *Off =
11175ffd83dbSDimitry Andric           shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
11185ffd83dbSDimitry Andric                      DObj->getEHFrameSection().Data)) {
11195ffd83dbSDimitry Andric     if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
1120bdd1243dSDimitry Andric       (*DF)->dump(OS, DumpOpts, *Off);
11215ffd83dbSDimitry Andric     else
11225ffd83dbSDimitry Andric       RecoverableErrorHandler(DF.takeError());
11235ffd83dbSDimitry Andric   }
11245ffd83dbSDimitry Andric 
11255ffd83dbSDimitry Andric   if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
11265ffd83dbSDimitry Andric                  DObj->getMacroSection().Data)) {
11275ffd83dbSDimitry Andric     if (auto Macro = getDebugMacro())
11285ffd83dbSDimitry Andric       Macro->dump(OS);
11295ffd83dbSDimitry Andric   }
11305ffd83dbSDimitry Andric 
11315ffd83dbSDimitry Andric   if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
11325ffd83dbSDimitry Andric                  DObj->getMacroDWOSection())) {
11335ffd83dbSDimitry Andric     if (auto MacroDWO = getDebugMacroDWO())
11345ffd83dbSDimitry Andric       MacroDWO->dump(OS);
11355ffd83dbSDimitry Andric   }
11365ffd83dbSDimitry Andric 
11375ffd83dbSDimitry Andric   if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
11385ffd83dbSDimitry Andric                  DObj->getMacinfoSection())) {
11395ffd83dbSDimitry Andric     if (auto Macinfo = getDebugMacinfo())
11405ffd83dbSDimitry Andric       Macinfo->dump(OS);
11415ffd83dbSDimitry Andric   }
11425ffd83dbSDimitry Andric 
11435ffd83dbSDimitry Andric   if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
11445ffd83dbSDimitry Andric                  DObj->getMacinfoDWOSection())) {
11455ffd83dbSDimitry Andric     if (auto MacinfoDWO = getDebugMacinfoDWO())
11465ffd83dbSDimitry Andric       MacinfoDWO->dump(OS);
11470b57cec5SDimitry Andric   }
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
11508bcb0991SDimitry Andric                  DObj->getArangesSection())) {
11518bcb0991SDimitry Andric     uint64_t offset = 0;
11525ffd83dbSDimitry Andric     DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
11535ffd83dbSDimitry Andric                                    0);
11540b57cec5SDimitry Andric     DWARFDebugArangeSet set;
11555ffd83dbSDimitry Andric     while (arangesData.isValidOffset(offset)) {
1156e8d8bef9SDimitry Andric       if (Error E =
1157e8d8bef9SDimitry Andric               set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
11585ffd83dbSDimitry Andric         RecoverableErrorHandler(std::move(E));
11595ffd83dbSDimitry Andric         break;
11605ffd83dbSDimitry Andric       }
11610b57cec5SDimitry Andric       set.dump(OS);
11620b57cec5SDimitry Andric     }
11635ffd83dbSDimitry Andric   }
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
11660b57cec5SDimitry Andric                              DIDumpOptions DumpOpts,
1167bdd1243dSDimitry Andric                              std::optional<uint64_t> DumpOffset) {
11680b57cec5SDimitry Andric     while (!Parser.done()) {
11690b57cec5SDimitry Andric       if (DumpOffset && Parser.getOffset() != *DumpOffset) {
11705ffd83dbSDimitry Andric         Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
11710b57cec5SDimitry Andric         continue;
11720b57cec5SDimitry Andric       }
11738bcb0991SDimitry Andric       OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
11748bcb0991SDimitry Andric          << "]\n";
11755ffd83dbSDimitry Andric       Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
11765ffd83dbSDimitry Andric                        DumpOpts.Verbose);
11770b57cec5SDimitry Andric     }
11780b57cec5SDimitry Andric   };
11790b57cec5SDimitry Andric 
1180e8d8bef9SDimitry Andric   auto DumpStrSection = [&](StringRef Section) {
1181e8d8bef9SDimitry Andric     DataExtractor StrData(Section, isLittleEndian(), 0);
1182e8d8bef9SDimitry Andric     uint64_t Offset = 0;
1183e8d8bef9SDimitry Andric     uint64_t StrOffset = 0;
1184e8d8bef9SDimitry Andric     while (StrData.isValidOffset(Offset)) {
1185e8d8bef9SDimitry Andric       Error Err = Error::success();
1186e8d8bef9SDimitry Andric       const char *CStr = StrData.getCStr(&Offset, &Err);
1187e8d8bef9SDimitry Andric       if (Err) {
1188e8d8bef9SDimitry Andric         DumpOpts.WarningHandler(std::move(Err));
1189e8d8bef9SDimitry Andric         return;
1190e8d8bef9SDimitry Andric       }
1191e8d8bef9SDimitry Andric       OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
1192e8d8bef9SDimitry Andric       OS.write_escaped(CStr);
1193e8d8bef9SDimitry Andric       OS << "\"\n";
1194e8d8bef9SDimitry Andric       StrOffset = Offset;
1195e8d8bef9SDimitry Andric     }
1196e8d8bef9SDimitry Andric   };
1197e8d8bef9SDimitry Andric 
11980b57cec5SDimitry Andric   if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
11990b57cec5SDimitry Andric                                    DObj->getLineSection().Data)) {
12000b57cec5SDimitry Andric     DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
12010b57cec5SDimitry Andric                                 0);
1202e8d8bef9SDimitry Andric     DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
12030b57cec5SDimitry Andric     DumpLineSection(Parser, DumpOpts, *Off);
12040b57cec5SDimitry Andric   }
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   if (const auto *Off =
12070b57cec5SDimitry Andric           shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
12080b57cec5SDimitry Andric                      DObj->getLineDWOSection().Data)) {
12090b57cec5SDimitry Andric     DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
12100b57cec5SDimitry Andric                                 isLittleEndian(), 0);
1211e8d8bef9SDimitry Andric     DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
12120b57cec5SDimitry Andric     DumpLineSection(Parser, DumpOpts, *Off);
12130b57cec5SDimitry Andric   }
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
12160b57cec5SDimitry Andric                  DObj->getCUIndexSection())) {
12170b57cec5SDimitry Andric     getCUIndex().dump(OS);
12180b57cec5SDimitry Andric   }
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
12210b57cec5SDimitry Andric                  DObj->getTUIndexSection())) {
12220b57cec5SDimitry Andric     getTUIndex().dump(OS);
12230b57cec5SDimitry Andric   }
12240b57cec5SDimitry Andric 
12250b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
1226e8d8bef9SDimitry Andric                  DObj->getStrSection()))
1227e8d8bef9SDimitry Andric     DumpStrSection(DObj->getStrSection());
1228e8d8bef9SDimitry Andric 
12290b57cec5SDimitry Andric   if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
1230e8d8bef9SDimitry Andric                  DObj->getStrDWOSection()))
1231e8d8bef9SDimitry Andric     DumpStrSection(DObj->getStrDWOSection());
1232e8d8bef9SDimitry Andric 
12330b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
1234e8d8bef9SDimitry Andric                  DObj->getLineStrSection()))
1235e8d8bef9SDimitry Andric     DumpStrSection(DObj->getLineStrSection());
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
12380b57cec5SDimitry Andric                  DObj->getAddrSection().Data)) {
12390b57cec5SDimitry Andric     DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
12400b57cec5SDimitry Andric                                    isLittleEndian(), 0);
12410b57cec5SDimitry Andric     dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
12420b57cec5SDimitry Andric   }
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
12458bcb0991SDimitry Andric                  DObj->getRangesSection().Data)) {
12460b57cec5SDimitry Andric     uint8_t savedAddressByteSize = getCUAddrSize();
12478bcb0991SDimitry Andric     DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
12480b57cec5SDimitry Andric                                   isLittleEndian(), savedAddressByteSize);
12498bcb0991SDimitry Andric     uint64_t offset = 0;
12500b57cec5SDimitry Andric     DWARFDebugRangeList rangeList;
12510b57cec5SDimitry Andric     while (rangesData.isValidOffset(offset)) {
12520b57cec5SDimitry Andric       if (Error E = rangeList.extract(rangesData, &offset)) {
12535ffd83dbSDimitry Andric         DumpOpts.RecoverableErrorHandler(std::move(E));
12540b57cec5SDimitry Andric         break;
12550b57cec5SDimitry Andric       }
12560b57cec5SDimitry Andric       rangeList.dump(OS);
12570b57cec5SDimitry Andric     }
12580b57cec5SDimitry Andric   }
12590b57cec5SDimitry Andric 
1260bdd1243dSDimitry Andric   auto LookupPooledAddress =
1261bdd1243dSDimitry Andric       [&](uint32_t Index) -> std::optional<SectionedAddress> {
12620b57cec5SDimitry Andric     const auto &CUs = compile_units();
12630b57cec5SDimitry Andric     auto I = CUs.begin();
12640b57cec5SDimitry Andric     if (I == CUs.end())
1265bdd1243dSDimitry Andric       return std::nullopt;
12660b57cec5SDimitry Andric     return (*I)->getAddrOffsetSectionItem(Index);
12670b57cec5SDimitry Andric   };
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
12700b57cec5SDimitry Andric                  DObj->getRnglistsSection().Data)) {
12710b57cec5SDimitry Andric     DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
12720b57cec5SDimitry Andric                                    isLittleEndian(), 0);
12730b57cec5SDimitry Andric     dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
12740b57cec5SDimitry Andric   }
12750b57cec5SDimitry Andric 
12760b57cec5SDimitry Andric   if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
12770b57cec5SDimitry Andric                  DObj->getRnglistsDWOSection().Data)) {
12780b57cec5SDimitry Andric     DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
12790b57cec5SDimitry Andric                                    isLittleEndian(), 0);
12800b57cec5SDimitry Andric     dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
12810b57cec5SDimitry Andric   }
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
12845ffd83dbSDimitry Andric                  DObj->getPubnamesSection().Data)) {
12855ffd83dbSDimitry Andric     DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
12865ffd83dbSDimitry Andric                                     isLittleEndian(), 0);
12875ffd83dbSDimitry Andric     dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
12885ffd83dbSDimitry Andric   }
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
12915ffd83dbSDimitry Andric                  DObj->getPubtypesSection().Data)) {
12925ffd83dbSDimitry Andric     DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
12935ffd83dbSDimitry Andric                                     isLittleEndian(), 0);
12945ffd83dbSDimitry Andric     dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
12955ffd83dbSDimitry Andric   }
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
12985ffd83dbSDimitry Andric                  DObj->getGnuPubnamesSection().Data)) {
12995ffd83dbSDimitry Andric     DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
13005ffd83dbSDimitry Andric                                     isLittleEndian(), 0);
13015ffd83dbSDimitry Andric     dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
13025ffd83dbSDimitry Andric   }
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
13055ffd83dbSDimitry Andric                  DObj->getGnuPubtypesSection().Data)) {
13065ffd83dbSDimitry Andric     DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
13075ffd83dbSDimitry Andric                                     isLittleEndian(), 0);
13085ffd83dbSDimitry Andric     dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
13095ffd83dbSDimitry Andric   }
13100b57cec5SDimitry Andric 
13110b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
13128bcb0991SDimitry Andric                  DObj->getStrOffsetsSection().Data))
13135ffd83dbSDimitry Andric     dumpStringOffsetsSection(
13145ffd83dbSDimitry Andric         OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
13155ffd83dbSDimitry Andric         DObj->getStrSection(), normal_units(), isLittleEndian());
13160b57cec5SDimitry Andric   if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
13178bcb0991SDimitry Andric                  DObj->getStrOffsetsDWOSection().Data))
13185ffd83dbSDimitry Andric     dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
13198bcb0991SDimitry Andric                              DObj->getStrOffsetsDWOSection(),
13208bcb0991SDimitry Andric                              DObj->getStrDWOSection(), dwo_units(),
13215ffd83dbSDimitry Andric                              isLittleEndian());
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric   if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
13240b57cec5SDimitry Andric                  DObj->getGdbIndexSection())) {
13250b57cec5SDimitry Andric     getGdbIndex().dump(OS);
13260b57cec5SDimitry Andric   }
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric   if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
13290b57cec5SDimitry Andric                  DObj->getAppleNamesSection().Data))
13300b57cec5SDimitry Andric     getAppleNames().dump(OS);
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
13330b57cec5SDimitry Andric                  DObj->getAppleTypesSection().Data))
13340b57cec5SDimitry Andric     getAppleTypes().dump(OS);
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric   if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
13370b57cec5SDimitry Andric                  DObj->getAppleNamespacesSection().Data))
13380b57cec5SDimitry Andric     getAppleNamespaces().dump(OS);
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
13410b57cec5SDimitry Andric                  DObj->getAppleObjCSection().Data))
13420b57cec5SDimitry Andric     getAppleObjC().dump(OS);
13430b57cec5SDimitry Andric   if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
13448bcb0991SDimitry Andric                  DObj->getNamesSection().Data))
13450b57cec5SDimitry Andric     getDebugNames().dump(OS);
13460b57cec5SDimitry Andric }
13470b57cec5SDimitry Andric 
1348349cc55cSDimitry Andric DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint16_t Version, uint64_t Hash,
1349349cc55cSDimitry Andric                                                 bool IsDWO) {
13505f757f3fSDimitry Andric   DWARFUnitVector &DWOUnits = State->getDWOUnits();
135104eeddc0SDimitry Andric   if (const auto &TUI = getTUIndex()) {
135204eeddc0SDimitry Andric     if (const auto *R = TUI.getFromHash(Hash))
135304eeddc0SDimitry Andric       return dyn_cast_or_null<DWARFTypeUnit>(
135404eeddc0SDimitry Andric           DWOUnits.getUnitForIndexEntry(*R));
1355349cc55cSDimitry Andric     return nullptr;
1356349cc55cSDimitry Andric   }
13577a6dacacSDimitry Andric   return State->getTypeUnitMap(IsDWO).lookup(Hash);
135804eeddc0SDimitry Andric }
135904eeddc0SDimitry Andric 
13600b57cec5SDimitry Andric DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
13615f757f3fSDimitry Andric   DWARFUnitVector &DWOUnits = State->getDWOUnits(LazyParse);
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric   if (const auto &CUI = getCUIndex()) {
13640b57cec5SDimitry Andric     if (const auto *R = CUI.getFromHash(Hash))
13650b57cec5SDimitry Andric       return dyn_cast_or_null<DWARFCompileUnit>(
13660b57cec5SDimitry Andric           DWOUnits.getUnitForIndexEntry(*R));
13670b57cec5SDimitry Andric     return nullptr;
13680b57cec5SDimitry Andric   }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric   // If there's no index, just search through the CUs in the DWO - there's
13710b57cec5SDimitry Andric   // probably only one unless this is something like LTO - though an in-process
13720b57cec5SDimitry Andric   // built/cached lookup table could be used in that case to improve repeated
13730b57cec5SDimitry Andric   // lookups of different CUs in the DWO.
13740b57cec5SDimitry Andric   for (const auto &DWOCU : dwo_compile_units()) {
13750b57cec5SDimitry Andric     // Might not have parsed DWO ID yet.
13760b57cec5SDimitry Andric     if (!DWOCU->getDWOId()) {
1377bdd1243dSDimitry Andric       if (std::optional<uint64_t> DWOId =
13780b57cec5SDimitry Andric               toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
13790b57cec5SDimitry Andric         DWOCU->setDWOId(*DWOId);
13800b57cec5SDimitry Andric       else
13810b57cec5SDimitry Andric         // No DWO ID?
13820b57cec5SDimitry Andric         continue;
13830b57cec5SDimitry Andric     }
13840b57cec5SDimitry Andric     if (DWOCU->getDWOId() == Hash)
13850b57cec5SDimitry Andric       return dyn_cast<DWARFCompileUnit>(DWOCU.get());
13860b57cec5SDimitry Andric   }
13870b57cec5SDimitry Andric   return nullptr;
13880b57cec5SDimitry Andric }
13890b57cec5SDimitry Andric 
13908bcb0991SDimitry Andric DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
13915f757f3fSDimitry Andric   if (auto *CU = State->getNormalUnits().getUnitForOffset(Offset))
13920b57cec5SDimitry Andric     return CU->getDIEForOffset(Offset);
13930b57cec5SDimitry Andric   return DWARFDie();
13940b57cec5SDimitry Andric }
13950b57cec5SDimitry Andric 
13960b57cec5SDimitry Andric bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
13970b57cec5SDimitry Andric   bool Success = true;
13980b57cec5SDimitry Andric   DWARFVerifier verifier(OS, *this, DumpOpts);
13990b57cec5SDimitry Andric 
14000b57cec5SDimitry Andric   Success &= verifier.handleDebugAbbrev();
140181ad6265SDimitry Andric   if (DumpOpts.DumpType & DIDT_DebugCUIndex)
140281ad6265SDimitry Andric     Success &= verifier.handleDebugCUIndex();
140381ad6265SDimitry Andric   if (DumpOpts.DumpType & DIDT_DebugTUIndex)
140481ad6265SDimitry Andric     Success &= verifier.handleDebugTUIndex();
14050b57cec5SDimitry Andric   if (DumpOpts.DumpType & DIDT_DebugInfo)
14060b57cec5SDimitry Andric     Success &= verifier.handleDebugInfo();
14070b57cec5SDimitry Andric   if (DumpOpts.DumpType & DIDT_DebugLine)
14080b57cec5SDimitry Andric     Success &= verifier.handleDebugLine();
140906c3fb27SDimitry Andric   if (DumpOpts.DumpType & DIDT_DebugStrOffsets)
141006c3fb27SDimitry Andric     Success &= verifier.handleDebugStrOffsets();
14110b57cec5SDimitry Andric   Success &= verifier.handleAccelTables();
1412*0fca6ea1SDimitry Andric   verifier.summarize();
14130b57cec5SDimitry Andric   return Success;
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric const DWARFUnitIndex &DWARFContext::getCUIndex() {
14175f757f3fSDimitry Andric   return State->getCUIndex();
14180b57cec5SDimitry Andric }
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric const DWARFUnitIndex &DWARFContext::getTUIndex() {
14215f757f3fSDimitry Andric   return State->getTUIndex();
14220b57cec5SDimitry Andric }
14230b57cec5SDimitry Andric 
14240b57cec5SDimitry Andric DWARFGdbIndex &DWARFContext::getGdbIndex() {
14255f757f3fSDimitry Andric   return State->getGdbIndex();
14260b57cec5SDimitry Andric }
14270b57cec5SDimitry Andric 
14280b57cec5SDimitry Andric const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
14295f757f3fSDimitry Andric   return State->getDebugAbbrev();
14300b57cec5SDimitry Andric }
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
14335f757f3fSDimitry Andric   return State->getDebugAbbrevDWO();
14340b57cec5SDimitry Andric }
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric const DWARFDebugLoc *DWARFContext::getDebugLoc() {
14375f757f3fSDimitry Andric   return State->getDebugLoc();
14380b57cec5SDimitry Andric }
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric const DWARFDebugAranges *DWARFContext::getDebugAranges() {
14415f757f3fSDimitry Andric   return State->getDebugAranges();
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
14445ffd83dbSDimitry Andric Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
14455f757f3fSDimitry Andric   return State->getDebugFrame();
14460b57cec5SDimitry Andric }
14470b57cec5SDimitry Andric 
14485ffd83dbSDimitry Andric Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
14495f757f3fSDimitry Andric   return State->getEHFrame();
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric 
14525ffd83dbSDimitry Andric const DWARFDebugMacro *DWARFContext::getDebugMacro() {
14535f757f3fSDimitry Andric   return State->getDebugMacro();
14545ffd83dbSDimitry Andric }
1455480093f4SDimitry Andric 
14565ffd83dbSDimitry Andric const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() {
14575f757f3fSDimitry Andric   return State->getDebugMacroDWO();
1458480093f4SDimitry Andric }
1459480093f4SDimitry Andric 
14605ffd83dbSDimitry Andric const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
14615f757f3fSDimitry Andric   return State->getDebugMacinfo();
14625ffd83dbSDimitry Andric }
14630b57cec5SDimitry Andric 
14645ffd83dbSDimitry Andric const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
14655f757f3fSDimitry Andric   return State->getDebugMacinfoDWO();
14660b57cec5SDimitry Andric }
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric const DWARFDebugNames &DWARFContext::getDebugNames() {
14705f757f3fSDimitry Andric   return State->getDebugNames();
14710b57cec5SDimitry Andric }
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric const AppleAcceleratorTable &DWARFContext::getAppleNames() {
14745f757f3fSDimitry Andric   return State->getAppleNames();
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric 
14770b57cec5SDimitry Andric const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
14785f757f3fSDimitry Andric   return State->getAppleTypes();
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
14825f757f3fSDimitry Andric   return State->getAppleNamespaces();
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
14865f757f3fSDimitry Andric   return State->getAppleObjC();
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric const DWARFDebugLine::LineTable *
14900b57cec5SDimitry Andric DWARFContext::getLineTableForUnit(DWARFUnit *U) {
14910b57cec5SDimitry Andric   Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
14925ffd83dbSDimitry Andric       getLineTableForUnit(U, WarningHandler);
14930b57cec5SDimitry Andric   if (!ExpectedLineTable) {
14945ffd83dbSDimitry Andric     WarningHandler(ExpectedLineTable.takeError());
14950b57cec5SDimitry Andric     return nullptr;
14960b57cec5SDimitry Andric   }
14970b57cec5SDimitry Andric   return *ExpectedLineTable;
14980b57cec5SDimitry Andric }
14990b57cec5SDimitry Andric 
15000b57cec5SDimitry Andric Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
15015ffd83dbSDimitry Andric     DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
15025f757f3fSDimitry Andric   return State->getLineTableForUnit(U, RecoverableErrorHandler);
15030b57cec5SDimitry Andric }
15040b57cec5SDimitry Andric 
150581ad6265SDimitry Andric void DWARFContext::clearLineTableForUnit(DWARFUnit *U) {
15065f757f3fSDimitry Andric   return State->clearLineTableForUnit(U);
150781ad6265SDimitry Andric }
150881ad6265SDimitry Andric 
15095f757f3fSDimitry Andric DWARFUnitVector &DWARFContext::getDWOUnits(bool Lazy) {
15105f757f3fSDimitry Andric   return State->getDWOUnits(Lazy);
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric 
15138bcb0991SDimitry Andric DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
15140b57cec5SDimitry Andric   return dyn_cast_or_null<DWARFCompileUnit>(
15155f757f3fSDimitry Andric       State->getNormalUnits().getUnitForOffset(Offset));
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric 
151806c3fb27SDimitry Andric DWARFCompileUnit *DWARFContext::getCompileUnitForCodeAddress(uint64_t Address) {
15198bcb0991SDimitry Andric   uint64_t CUOffset = getDebugAranges()->findAddress(Address);
152006c3fb27SDimitry Andric   return getCompileUnitForOffset(CUOffset);
152106c3fb27SDimitry Andric }
152206c3fb27SDimitry Andric 
152306c3fb27SDimitry Andric DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
152406c3fb27SDimitry Andric   uint64_t CUOffset = getDebugAranges()->findAddress(Address);
152581ad6265SDimitry Andric   if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
152681ad6265SDimitry Andric     return OffsetCU;
152781ad6265SDimitry Andric 
152806c3fb27SDimitry Andric   // Global variables are often missed by the above search, for one of two
152981ad6265SDimitry Andric   // reasons:
153081ad6265SDimitry Andric   //   1. .debug_aranges may not include global variables. On clang, it seems we
153181ad6265SDimitry Andric   //      put the globals in the aranges, but this isn't true for gcc.
153281ad6265SDimitry Andric   //   2. Even if the global variable is in a .debug_arange, global variables
153381ad6265SDimitry Andric   //      may not be captured in the [start, end) addresses described by the
153481ad6265SDimitry Andric   //      parent compile unit.
153581ad6265SDimitry Andric   //
153681ad6265SDimitry Andric   // So, we walk the CU's and their child DI's manually, looking for the
153781ad6265SDimitry Andric   // specific global variable.
153881ad6265SDimitry Andric   for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
15395f757f3fSDimitry Andric     if (CU->getVariableForAddress(Address)) {
154081ad6265SDimitry Andric       return static_cast<DWARFCompileUnit *>(CU.get());
154181ad6265SDimitry Andric     }
154281ad6265SDimitry Andric   }
154381ad6265SDimitry Andric   return nullptr;
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15467a6dacacSDimitry Andric DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address,
15477a6dacacSDimitry Andric                                                              bool CheckDWO) {
15480b57cec5SDimitry Andric   DIEsForAddress Result;
15490b57cec5SDimitry Andric 
155006c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address);
15510b57cec5SDimitry Andric   if (!CU)
15520b57cec5SDimitry Andric     return Result;
15530b57cec5SDimitry Andric 
15547a6dacacSDimitry Andric   if (CheckDWO) {
15557a6dacacSDimitry Andric     // We were asked to check the DWO file and this debug information is more
15567a6dacacSDimitry Andric     // complete that any information in the skeleton compile unit, so search the
15577a6dacacSDimitry Andric     // DWO first to see if we have a match.
15587a6dacacSDimitry Andric     DWARFDie CUDie = CU->getUnitDIE(false);
15597a6dacacSDimitry Andric     DWARFDie CUDwoDie = CU->getNonSkeletonUnitDIE(false);
15607a6dacacSDimitry Andric     if (CheckDWO && CUDwoDie && CUDie != CUDwoDie) {
15617a6dacacSDimitry Andric       // We have a DWO file, lets search it.
15627a6dacacSDimitry Andric       DWARFCompileUnit *CUDwo =
15637a6dacacSDimitry Andric           dyn_cast_or_null<DWARFCompileUnit>(CUDwoDie.getDwarfUnit());
15647a6dacacSDimitry Andric       if (CUDwo) {
15657a6dacacSDimitry Andric         Result.FunctionDIE = CUDwo->getSubroutineForAddress(Address);
15667a6dacacSDimitry Andric         if (Result.FunctionDIE)
15677a6dacacSDimitry Andric           Result.CompileUnit = CUDwo;
15687a6dacacSDimitry Andric       }
15697a6dacacSDimitry Andric     }
15707a6dacacSDimitry Andric   }
15717a6dacacSDimitry Andric 
15727a6dacacSDimitry Andric   // Search the normal DWARF if we didn't find a match in the DWO file or if
15737a6dacacSDimitry Andric   // we didn't check the DWO file above.
15747a6dacacSDimitry Andric   if (!Result) {
15750b57cec5SDimitry Andric     Result.CompileUnit = CU;
15760b57cec5SDimitry Andric     Result.FunctionDIE = CU->getSubroutineForAddress(Address);
15777a6dacacSDimitry Andric   }
15780b57cec5SDimitry Andric 
15790b57cec5SDimitry Andric   std::vector<DWARFDie> Worklist;
15800b57cec5SDimitry Andric   Worklist.push_back(Result.FunctionDIE);
15810b57cec5SDimitry Andric   while (!Worklist.empty()) {
15820b57cec5SDimitry Andric     DWARFDie DIE = Worklist.back();
15830b57cec5SDimitry Andric     Worklist.pop_back();
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric     if (!DIE.isValid())
15860b57cec5SDimitry Andric       continue;
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric     if (DIE.getTag() == DW_TAG_lexical_block &&
15890b57cec5SDimitry Andric         DIE.addressRangeContainsAddress(Address)) {
15900b57cec5SDimitry Andric       Result.BlockDIE = DIE;
15910b57cec5SDimitry Andric       break;
15920b57cec5SDimitry Andric     }
15930b57cec5SDimitry Andric 
1594fe6060f1SDimitry Andric     append_range(Worklist, DIE);
15950b57cec5SDimitry Andric   }
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   return Result;
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric /// TODO: change input parameter from "uint64_t Address"
16010b57cec5SDimitry Andric ///       into "SectionedAddress Address"
1602fe6060f1SDimitry Andric static bool getFunctionNameAndStartLineForAddress(
1603fe6060f1SDimitry Andric     DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind,
1604e8d8bef9SDimitry Andric     DILineInfoSpecifier::FileLineInfoKind FileNameKind,
1605fe6060f1SDimitry Andric     std::string &FunctionName, std::string &StartFile, uint32_t &StartLine,
1606bdd1243dSDimitry Andric     std::optional<uint64_t> &StartAddress) {
16070b57cec5SDimitry Andric   // The address may correspond to instruction in some inlined function,
16080b57cec5SDimitry Andric   // so we have to build the chain of inlined functions and take the
16090b57cec5SDimitry Andric   // name of the topmost function in it.
16100b57cec5SDimitry Andric   SmallVector<DWARFDie, 4> InlinedChain;
16110b57cec5SDimitry Andric   CU->getInlinedChainForAddress(Address, InlinedChain);
16120b57cec5SDimitry Andric   if (InlinedChain.empty())
16130b57cec5SDimitry Andric     return false;
16140b57cec5SDimitry Andric 
16150b57cec5SDimitry Andric   const DWARFDie &DIE = InlinedChain[0];
16160b57cec5SDimitry Andric   bool FoundResult = false;
16170b57cec5SDimitry Andric   const char *Name = nullptr;
16180b57cec5SDimitry Andric   if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
16190b57cec5SDimitry Andric     FunctionName = Name;
16200b57cec5SDimitry Andric     FoundResult = true;
16210b57cec5SDimitry Andric   }
1622e8d8bef9SDimitry Andric   std::string DeclFile = DIE.getDeclFile(FileNameKind);
1623e8d8bef9SDimitry Andric   if (!DeclFile.empty()) {
1624e8d8bef9SDimitry Andric     StartFile = DeclFile;
1625e8d8bef9SDimitry Andric     FoundResult = true;
1626e8d8bef9SDimitry Andric   }
16270b57cec5SDimitry Andric   if (auto DeclLineResult = DIE.getDeclLine()) {
16280b57cec5SDimitry Andric     StartLine = DeclLineResult;
16290b57cec5SDimitry Andric     FoundResult = true;
16300b57cec5SDimitry Andric   }
1631fe6060f1SDimitry Andric   if (auto LowPcAddr = toSectionedAddress(DIE.find(DW_AT_low_pc)))
1632fe6060f1SDimitry Andric     StartAddress = LowPcAddr->Address;
16330b57cec5SDimitry Andric   return FoundResult;
16340b57cec5SDimitry Andric }
16350b57cec5SDimitry Andric 
1636bdd1243dSDimitry Andric static std::optional<int64_t>
1637480093f4SDimitry Andric getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
1638bdd1243dSDimitry Andric                          std::optional<unsigned> FrameBaseReg) {
1639480093f4SDimitry Andric   if (!Expr.empty() &&
1640480093f4SDimitry Andric       (Expr[0] == DW_OP_fbreg ||
1641480093f4SDimitry Andric        (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
1642480093f4SDimitry Andric     unsigned Count;
1643480093f4SDimitry Andric     int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
1644480093f4SDimitry Andric     // A single DW_OP_fbreg or DW_OP_breg.
1645480093f4SDimitry Andric     if (Expr.size() == Count + 1)
1646480093f4SDimitry Andric       return Offset;
1647480093f4SDimitry Andric     // Same + DW_OP_deref (Fortran arrays look like this).
1648480093f4SDimitry Andric     if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
1649480093f4SDimitry Andric       return Offset;
1650480093f4SDimitry Andric     // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
1651480093f4SDimitry Andric   }
1652bdd1243dSDimitry Andric   return std::nullopt;
1653480093f4SDimitry Andric }
1654480093f4SDimitry Andric 
16550b57cec5SDimitry Andric void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
16560b57cec5SDimitry Andric                                    DWARFDie Die, std::vector<DILocal> &Result) {
16570b57cec5SDimitry Andric   if (Die.getTag() == DW_TAG_variable ||
16580b57cec5SDimitry Andric       Die.getTag() == DW_TAG_formal_parameter) {
16590b57cec5SDimitry Andric     DILocal Local;
1660480093f4SDimitry Andric     if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
1661480093f4SDimitry Andric       Local.FunctionName = Name;
1662480093f4SDimitry Andric 
1663bdd1243dSDimitry Andric     std::optional<unsigned> FrameBaseReg;
1664480093f4SDimitry Andric     if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
1665bdd1243dSDimitry Andric       if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
1666480093f4SDimitry Andric         if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
1667480093f4SDimitry Andric             (*Expr)[0] <= DW_OP_reg31) {
1668480093f4SDimitry Andric           FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
1669480093f4SDimitry Andric         }
1670480093f4SDimitry Andric 
1671480093f4SDimitry Andric     if (Expected<std::vector<DWARFLocationExpression>> Loc =
1672480093f4SDimitry Andric             Die.getLocations(DW_AT_location)) {
1673480093f4SDimitry Andric       for (const auto &Entry : *Loc) {
1674bdd1243dSDimitry Andric         if (std::optional<int64_t> FrameOffset =
1675480093f4SDimitry Andric                 getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
1676480093f4SDimitry Andric           Local.FrameOffset = *FrameOffset;
1677480093f4SDimitry Andric           break;
1678480093f4SDimitry Andric         }
1679480093f4SDimitry Andric       }
1680480093f4SDimitry Andric     } else {
1681480093f4SDimitry Andric       // FIXME: missing DW_AT_location is OK here, but other errors should be
1682480093f4SDimitry Andric       // reported to the user.
1683480093f4SDimitry Andric       consumeError(Loc.takeError());
1684480093f4SDimitry Andric     }
1685480093f4SDimitry Andric 
16860b57cec5SDimitry Andric     if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
16870b57cec5SDimitry Andric       Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
16880b57cec5SDimitry Andric 
16890b57cec5SDimitry Andric     if (auto Origin =
16900b57cec5SDimitry Andric             Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
16910b57cec5SDimitry Andric       Die = Origin;
16920b57cec5SDimitry Andric     if (auto NameAttr = Die.find(DW_AT_name))
1693bdd1243dSDimitry Andric       if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
16940b57cec5SDimitry Andric         Local.Name = *Name;
16950b57cec5SDimitry Andric     if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
169681ad6265SDimitry Andric       Local.Size = Type.getTypeSize(getCUAddrSize());
16970b57cec5SDimitry Andric     if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
16980b57cec5SDimitry Andric       if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
16990b57cec5SDimitry Andric         LT->getFileNameByIndex(
1700bdd1243dSDimitry Andric             *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(),
17010b57cec5SDimitry Andric             DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
17020b57cec5SDimitry Andric             Local.DeclFile);
17030b57cec5SDimitry Andric     }
17040b57cec5SDimitry Andric     if (auto DeclLineAttr = Die.find(DW_AT_decl_line))
1705bdd1243dSDimitry Andric       Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant();
17060b57cec5SDimitry Andric 
17070b57cec5SDimitry Andric     Result.push_back(Local);
17080b57cec5SDimitry Andric     return;
17090b57cec5SDimitry Andric   }
17100b57cec5SDimitry Andric 
17110b57cec5SDimitry Andric   if (Die.getTag() == DW_TAG_inlined_subroutine)
17120b57cec5SDimitry Andric     if (auto Origin =
17130b57cec5SDimitry Andric             Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
17140b57cec5SDimitry Andric       Subprogram = Origin;
17150b57cec5SDimitry Andric 
17160b57cec5SDimitry Andric   for (auto Child : Die)
17170b57cec5SDimitry Andric     addLocalsForDie(CU, Subprogram, Child, Result);
17180b57cec5SDimitry Andric }
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric std::vector<DILocal>
17210b57cec5SDimitry Andric DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
17220b57cec5SDimitry Andric   std::vector<DILocal> Result;
172306c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
17240b57cec5SDimitry Andric   if (!CU)
17250b57cec5SDimitry Andric     return Result;
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address);
17280b57cec5SDimitry Andric   if (Subprogram.isValid())
17290b57cec5SDimitry Andric     addLocalsForDie(CU, Subprogram, Subprogram, Result);
17300b57cec5SDimitry Andric   return Result;
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
17340b57cec5SDimitry Andric                                                DILineInfoSpecifier Spec) {
17350b57cec5SDimitry Andric   DILineInfo Result;
173606c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
17370b57cec5SDimitry Andric   if (!CU)
17380b57cec5SDimitry Andric     return Result;
17390b57cec5SDimitry Andric 
1740fe6060f1SDimitry Andric   getFunctionNameAndStartLineForAddress(
1741fe6060f1SDimitry Andric       CU, Address.Address, Spec.FNKind, Spec.FLIKind, Result.FunctionName,
1742fe6060f1SDimitry Andric       Result.StartFileName, Result.StartLine, Result.StartAddress);
17430b57cec5SDimitry Andric   if (Spec.FLIKind != FileLineInfoKind::None) {
17440b57cec5SDimitry Andric     if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
17450b57cec5SDimitry Andric       LineTable->getFileLineInfoForAddress(
17460b57cec5SDimitry Andric           {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
17470b57cec5SDimitry Andric           Spec.FLIKind, Result);
17480b57cec5SDimitry Andric     }
17490b57cec5SDimitry Andric   }
175081ad6265SDimitry Andric 
175181ad6265SDimitry Andric   return Result;
175281ad6265SDimitry Andric }
175381ad6265SDimitry Andric 
175481ad6265SDimitry Andric DILineInfo
175581ad6265SDimitry Andric DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
175681ad6265SDimitry Andric   DILineInfo Result;
175706c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForDataAddress(Address.Address);
175881ad6265SDimitry Andric   if (!CU)
175981ad6265SDimitry Andric     return Result;
176081ad6265SDimitry Andric 
176181ad6265SDimitry Andric   if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
176281ad6265SDimitry Andric     Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
176381ad6265SDimitry Andric     Result.Line = Die.getDeclLine();
176481ad6265SDimitry Andric   }
176581ad6265SDimitry Andric 
17660b57cec5SDimitry Andric   return Result;
17670b57cec5SDimitry Andric }
17680b57cec5SDimitry Andric 
17690b57cec5SDimitry Andric DILineInfoTable DWARFContext::getLineInfoForAddressRange(
17700b57cec5SDimitry Andric     object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
17710b57cec5SDimitry Andric   DILineInfoTable Lines;
177206c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
17730b57cec5SDimitry Andric   if (!CU)
17740b57cec5SDimitry Andric     return Lines;
17750b57cec5SDimitry Andric 
17760b57cec5SDimitry Andric   uint32_t StartLine = 0;
1777e8d8bef9SDimitry Andric   std::string StartFileName;
17788bcb0991SDimitry Andric   std::string FunctionName(DILineInfo::BadString);
1779bdd1243dSDimitry Andric   std::optional<uint64_t> StartAddress;
1780fe6060f1SDimitry Andric   getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
1781fe6060f1SDimitry Andric                                         Spec.FLIKind, FunctionName,
1782fe6060f1SDimitry Andric                                         StartFileName, StartLine, StartAddress);
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric   // If the Specifier says we don't need FileLineInfo, just
17850b57cec5SDimitry Andric   // return the top-most function at the starting address.
17860b57cec5SDimitry Andric   if (Spec.FLIKind == FileLineInfoKind::None) {
17870b57cec5SDimitry Andric     DILineInfo Result;
17880b57cec5SDimitry Andric     Result.FunctionName = FunctionName;
1789e8d8bef9SDimitry Andric     Result.StartFileName = StartFileName;
17900b57cec5SDimitry Andric     Result.StartLine = StartLine;
1791fe6060f1SDimitry Andric     Result.StartAddress = StartAddress;
17920b57cec5SDimitry Andric     Lines.push_back(std::make_pair(Address.Address, Result));
17930b57cec5SDimitry Andric     return Lines;
17940b57cec5SDimitry Andric   }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
17970b57cec5SDimitry Andric 
17980b57cec5SDimitry Andric   // Get the index of row we're looking for in the line table.
17990b57cec5SDimitry Andric   std::vector<uint32_t> RowVector;
18000b57cec5SDimitry Andric   if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
18010b57cec5SDimitry Andric                                      Size, RowVector)) {
18020b57cec5SDimitry Andric     return Lines;
18030b57cec5SDimitry Andric   }
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   for (uint32_t RowIndex : RowVector) {
18060b57cec5SDimitry Andric     // Take file number and line/column from the row.
18070b57cec5SDimitry Andric     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
18080b57cec5SDimitry Andric     DILineInfo Result;
18090b57cec5SDimitry Andric     LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
18100b57cec5SDimitry Andric                                   Spec.FLIKind, Result.FileName);
18110b57cec5SDimitry Andric     Result.FunctionName = FunctionName;
18120b57cec5SDimitry Andric     Result.Line = Row.Line;
18130b57cec5SDimitry Andric     Result.Column = Row.Column;
1814e8d8bef9SDimitry Andric     Result.StartFileName = StartFileName;
18150b57cec5SDimitry Andric     Result.StartLine = StartLine;
1816fe6060f1SDimitry Andric     Result.StartAddress = StartAddress;
18170b57cec5SDimitry Andric     Lines.push_back(std::make_pair(Row.Address.Address, Result));
18180b57cec5SDimitry Andric   }
18190b57cec5SDimitry Andric 
18200b57cec5SDimitry Andric   return Lines;
18210b57cec5SDimitry Andric }
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric DIInliningInfo
18240b57cec5SDimitry Andric DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
18250b57cec5SDimitry Andric                                         DILineInfoSpecifier Spec) {
18260b57cec5SDimitry Andric   DIInliningInfo InliningInfo;
18270b57cec5SDimitry Andric 
182806c3fb27SDimitry Andric   DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
18290b57cec5SDimitry Andric   if (!CU)
18300b57cec5SDimitry Andric     return InliningInfo;
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric   const DWARFLineTable *LineTable = nullptr;
18330b57cec5SDimitry Andric   SmallVector<DWARFDie, 4> InlinedChain;
18340b57cec5SDimitry Andric   CU->getInlinedChainForAddress(Address.Address, InlinedChain);
18350b57cec5SDimitry Andric   if (InlinedChain.size() == 0) {
18360b57cec5SDimitry Andric     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
18370b57cec5SDimitry Andric     // try to at least get file/line info from symbol table.
18380b57cec5SDimitry Andric     if (Spec.FLIKind != FileLineInfoKind::None) {
18390b57cec5SDimitry Andric       DILineInfo Frame;
18400b57cec5SDimitry Andric       LineTable = getLineTableForUnit(CU);
18410b57cec5SDimitry Andric       if (LineTable && LineTable->getFileLineInfoForAddress(
18420b57cec5SDimitry Andric                            {Address.Address, Address.SectionIndex},
18430b57cec5SDimitry Andric                            CU->getCompilationDir(), Spec.FLIKind, Frame))
18440b57cec5SDimitry Andric         InliningInfo.addFrame(Frame);
18450b57cec5SDimitry Andric     }
18460b57cec5SDimitry Andric     return InliningInfo;
18470b57cec5SDimitry Andric   }
18480b57cec5SDimitry Andric 
18490b57cec5SDimitry Andric   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
18500b57cec5SDimitry Andric   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
18510b57cec5SDimitry Andric     DWARFDie &FunctionDIE = InlinedChain[i];
18520b57cec5SDimitry Andric     DILineInfo Frame;
18530b57cec5SDimitry Andric     // Get function name if necessary.
18540b57cec5SDimitry Andric     if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
18550b57cec5SDimitry Andric       Frame.FunctionName = Name;
18560b57cec5SDimitry Andric     if (auto DeclLineResult = FunctionDIE.getDeclLine())
18570b57cec5SDimitry Andric       Frame.StartLine = DeclLineResult;
1858e8d8bef9SDimitry Andric     Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
1859fe6060f1SDimitry Andric     if (auto LowPcAddr = toSectionedAddress(FunctionDIE.find(DW_AT_low_pc)))
1860fe6060f1SDimitry Andric       Frame.StartAddress = LowPcAddr->Address;
18610b57cec5SDimitry Andric     if (Spec.FLIKind != FileLineInfoKind::None) {
18620b57cec5SDimitry Andric       if (i == 0) {
18630b57cec5SDimitry Andric         // For the topmost frame, initialize the line table of this
18640b57cec5SDimitry Andric         // compile unit and fetch file/line info from it.
18650b57cec5SDimitry Andric         LineTable = getLineTableForUnit(CU);
18660b57cec5SDimitry Andric         // For the topmost routine, get file/line info from line table.
18670b57cec5SDimitry Andric         if (LineTable)
18680b57cec5SDimitry Andric           LineTable->getFileLineInfoForAddress(
18690b57cec5SDimitry Andric               {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
18700b57cec5SDimitry Andric               Spec.FLIKind, Frame);
18710b57cec5SDimitry Andric       } else {
18720b57cec5SDimitry Andric         // Otherwise, use call file, call line and call column from
18730b57cec5SDimitry Andric         // previous DIE in inlined chain.
18740b57cec5SDimitry Andric         if (LineTable)
18750b57cec5SDimitry Andric           LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
18760b57cec5SDimitry Andric                                         Spec.FLIKind, Frame.FileName);
18770b57cec5SDimitry Andric         Frame.Line = CallLine;
18780b57cec5SDimitry Andric         Frame.Column = CallColumn;
18790b57cec5SDimitry Andric         Frame.Discriminator = CallDiscriminator;
18800b57cec5SDimitry Andric       }
18810b57cec5SDimitry Andric       // Get call file/line/column of a current DIE.
18820b57cec5SDimitry Andric       if (i + 1 < n) {
18830b57cec5SDimitry Andric         FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
18840b57cec5SDimitry Andric                                    CallDiscriminator);
18850b57cec5SDimitry Andric       }
18860b57cec5SDimitry Andric     }
18870b57cec5SDimitry Andric     InliningInfo.addFrame(Frame);
18880b57cec5SDimitry Andric   }
18890b57cec5SDimitry Andric   return InliningInfo;
18900b57cec5SDimitry Andric }
18910b57cec5SDimitry Andric 
18920b57cec5SDimitry Andric std::shared_ptr<DWARFContext>
18930b57cec5SDimitry Andric DWARFContext::getDWOContext(StringRef AbsolutePath) {
18945f757f3fSDimitry Andric   return State->getDWOContext(AbsolutePath);
18950b57cec5SDimitry Andric }
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric static Error createError(const Twine &Reason, llvm::Error E) {
18980b57cec5SDimitry Andric   return make_error<StringError>(Reason + toString(std::move(E)),
18990b57cec5SDimitry Andric                                  inconvertibleErrorCode());
19000b57cec5SDimitry Andric }
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric /// SymInfo contains information about symbol: it's address
19030b57cec5SDimitry Andric /// and section index which is -1LL for absolute symbols.
19040b57cec5SDimitry Andric struct SymInfo {
19050b57cec5SDimitry Andric   uint64_t Address;
19060b57cec5SDimitry Andric   uint64_t SectionIndex;
19070b57cec5SDimitry Andric };
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric /// Returns the address of symbol relocation used against and a section index.
19100b57cec5SDimitry Andric /// Used for futher relocations computation. Symbol's section load address is
19110b57cec5SDimitry Andric static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
19120b57cec5SDimitry Andric                                        const RelocationRef &Reloc,
19130b57cec5SDimitry Andric                                        const LoadedObjectInfo *L,
19140b57cec5SDimitry Andric                                        std::map<SymbolRef, SymInfo> &Cache) {
19150b57cec5SDimitry Andric   SymInfo Ret = {0, (uint64_t)-1LL};
19160b57cec5SDimitry Andric   object::section_iterator RSec = Obj.section_end();
19170b57cec5SDimitry Andric   object::symbol_iterator Sym = Reloc.getSymbol();
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric   std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
19200b57cec5SDimitry Andric   // First calculate the address of the symbol or section as it appears
19210b57cec5SDimitry Andric   // in the object file
19220b57cec5SDimitry Andric   if (Sym != Obj.symbol_end()) {
19230b57cec5SDimitry Andric     bool New;
19240b57cec5SDimitry Andric     std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
19250b57cec5SDimitry Andric     if (!New)
19260b57cec5SDimitry Andric       return CacheIt->second;
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric     Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
19290b57cec5SDimitry Andric     if (!SymAddrOrErr)
19300b57cec5SDimitry Andric       return createError("failed to compute symbol address: ",
19310b57cec5SDimitry Andric                          SymAddrOrErr.takeError());
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric     // Also remember what section this symbol is in for later
19340b57cec5SDimitry Andric     auto SectOrErr = Sym->getSection();
19350b57cec5SDimitry Andric     if (!SectOrErr)
19360b57cec5SDimitry Andric       return createError("failed to get symbol section: ",
19370b57cec5SDimitry Andric                          SectOrErr.takeError());
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric     RSec = *SectOrErr;
19400b57cec5SDimitry Andric     Ret.Address = *SymAddrOrErr;
19410b57cec5SDimitry Andric   } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
19420b57cec5SDimitry Andric     RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
19430b57cec5SDimitry Andric     Ret.Address = RSec->getAddress();
19440b57cec5SDimitry Andric   }
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   if (RSec != Obj.section_end())
19470b57cec5SDimitry Andric     Ret.SectionIndex = RSec->getIndex();
19480b57cec5SDimitry Andric 
19490b57cec5SDimitry Andric   // If we are given load addresses for the sections, we need to adjust:
19500b57cec5SDimitry Andric   // SymAddr = (Address of Symbol Or Section in File) -
19510b57cec5SDimitry Andric   //           (Address of Section in File) +
19520b57cec5SDimitry Andric   //           (Load Address of Section)
19530b57cec5SDimitry Andric   // RSec is now either the section being targeted or the section
19540b57cec5SDimitry Andric   // containing the symbol being targeted. In either case,
19550b57cec5SDimitry Andric   // we need to perform the same computation.
19560b57cec5SDimitry Andric   if (L && RSec != Obj.section_end())
19570b57cec5SDimitry Andric     if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
19580b57cec5SDimitry Andric       Ret.Address += SectionLoadAddress - RSec->getAddress();
19590b57cec5SDimitry Andric 
19600b57cec5SDimitry Andric   if (CacheIt != Cache.end())
19610b57cec5SDimitry Andric     CacheIt->second = Ret;
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric   return Ret;
19640b57cec5SDimitry Andric }
19650b57cec5SDimitry Andric 
19660b57cec5SDimitry Andric static bool isRelocScattered(const object::ObjectFile &Obj,
19670b57cec5SDimitry Andric                              const RelocationRef &Reloc) {
19680b57cec5SDimitry Andric   const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
19690b57cec5SDimitry Andric   if (!MachObj)
19700b57cec5SDimitry Andric     return false;
19710b57cec5SDimitry Andric   // MachO also has relocations that point to sections and
19720b57cec5SDimitry Andric   // scattered relocations.
19730b57cec5SDimitry Andric   auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
19740b57cec5SDimitry Andric   return MachObj->isRelocationScattered(RelocInfo);
19750b57cec5SDimitry Andric }
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric namespace {
19780b57cec5SDimitry Andric struct DWARFSectionMap final : public DWARFSection {
19790b57cec5SDimitry Andric   RelocAddrMap Relocs;
19800b57cec5SDimitry Andric };
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric class DWARFObjInMemory final : public DWARFObject {
19830b57cec5SDimitry Andric   bool IsLittleEndian;
19840b57cec5SDimitry Andric   uint8_t AddressSize;
19850b57cec5SDimitry Andric   StringRef FileName;
19860b57cec5SDimitry Andric   const object::ObjectFile *Obj = nullptr;
19870b57cec5SDimitry Andric   std::vector<SectionName> SectionNames;
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric   using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
19900b57cec5SDimitry Andric                                    std::map<object::SectionRef, unsigned>>;
19910b57cec5SDimitry Andric 
19920b57cec5SDimitry Andric   InfoSectionMap InfoSections;
19930b57cec5SDimitry Andric   InfoSectionMap TypesSections;
19940b57cec5SDimitry Andric   InfoSectionMap InfoDWOSections;
19950b57cec5SDimitry Andric   InfoSectionMap TypesDWOSections;
19960b57cec5SDimitry Andric 
19970b57cec5SDimitry Andric   DWARFSectionMap LocSection;
19988bcb0991SDimitry Andric   DWARFSectionMap LoclistsSection;
1999480093f4SDimitry Andric   DWARFSectionMap LoclistsDWOSection;
20000b57cec5SDimitry Andric   DWARFSectionMap LineSection;
20018bcb0991SDimitry Andric   DWARFSectionMap RangesSection;
20020b57cec5SDimitry Andric   DWARFSectionMap RnglistsSection;
20038bcb0991SDimitry Andric   DWARFSectionMap StrOffsetsSection;
20040b57cec5SDimitry Andric   DWARFSectionMap LineDWOSection;
20058bcb0991SDimitry Andric   DWARFSectionMap FrameSection;
20060b57cec5SDimitry Andric   DWARFSectionMap EHFrameSection;
20070b57cec5SDimitry Andric   DWARFSectionMap LocDWOSection;
20088bcb0991SDimitry Andric   DWARFSectionMap StrOffsetsDWOSection;
20098bcb0991SDimitry Andric   DWARFSectionMap RangesDWOSection;
20100b57cec5SDimitry Andric   DWARFSectionMap RnglistsDWOSection;
20110b57cec5SDimitry Andric   DWARFSectionMap AddrSection;
20120b57cec5SDimitry Andric   DWARFSectionMap AppleNamesSection;
20130b57cec5SDimitry Andric   DWARFSectionMap AppleTypesSection;
20140b57cec5SDimitry Andric   DWARFSectionMap AppleNamespacesSection;
20150b57cec5SDimitry Andric   DWARFSectionMap AppleObjCSection;
20168bcb0991SDimitry Andric   DWARFSectionMap NamesSection;
20178bcb0991SDimitry Andric   DWARFSectionMap PubnamesSection;
20188bcb0991SDimitry Andric   DWARFSectionMap PubtypesSection;
20198bcb0991SDimitry Andric   DWARFSectionMap GnuPubnamesSection;
20208bcb0991SDimitry Andric   DWARFSectionMap GnuPubtypesSection;
20215ffd83dbSDimitry Andric   DWARFSectionMap MacroSection;
20220b57cec5SDimitry Andric 
20230b57cec5SDimitry Andric   DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
20240b57cec5SDimitry Andric     return StringSwitch<DWARFSectionMap *>(Name)
20250b57cec5SDimitry Andric         .Case("debug_loc", &LocSection)
20268bcb0991SDimitry Andric         .Case("debug_loclists", &LoclistsSection)
2027480093f4SDimitry Andric         .Case("debug_loclists.dwo", &LoclistsDWOSection)
20280b57cec5SDimitry Andric         .Case("debug_line", &LineSection)
20298bcb0991SDimitry Andric         .Case("debug_frame", &FrameSection)
20300b57cec5SDimitry Andric         .Case("eh_frame", &EHFrameSection)
20318bcb0991SDimitry Andric         .Case("debug_str_offsets", &StrOffsetsSection)
20328bcb0991SDimitry Andric         .Case("debug_ranges", &RangesSection)
20330b57cec5SDimitry Andric         .Case("debug_rnglists", &RnglistsSection)
20340b57cec5SDimitry Andric         .Case("debug_loc.dwo", &LocDWOSection)
20350b57cec5SDimitry Andric         .Case("debug_line.dwo", &LineDWOSection)
20368bcb0991SDimitry Andric         .Case("debug_names", &NamesSection)
20370b57cec5SDimitry Andric         .Case("debug_rnglists.dwo", &RnglistsDWOSection)
20388bcb0991SDimitry Andric         .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
20390b57cec5SDimitry Andric         .Case("debug_addr", &AddrSection)
20400b57cec5SDimitry Andric         .Case("apple_names", &AppleNamesSection)
20418bcb0991SDimitry Andric         .Case("debug_pubnames", &PubnamesSection)
20428bcb0991SDimitry Andric         .Case("debug_pubtypes", &PubtypesSection)
20438bcb0991SDimitry Andric         .Case("debug_gnu_pubnames", &GnuPubnamesSection)
20448bcb0991SDimitry Andric         .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
20450b57cec5SDimitry Andric         .Case("apple_types", &AppleTypesSection)
20460b57cec5SDimitry Andric         .Case("apple_namespaces", &AppleNamespacesSection)
20470b57cec5SDimitry Andric         .Case("apple_namespac", &AppleNamespacesSection)
20480b57cec5SDimitry Andric         .Case("apple_objc", &AppleObjCSection)
20495ffd83dbSDimitry Andric         .Case("debug_macro", &MacroSection)
20500b57cec5SDimitry Andric         .Default(nullptr);
20510b57cec5SDimitry Andric   }
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   StringRef AbbrevSection;
20548bcb0991SDimitry Andric   StringRef ArangesSection;
20558bcb0991SDimitry Andric   StringRef StrSection;
20560b57cec5SDimitry Andric   StringRef MacinfoSection;
2057480093f4SDimitry Andric   StringRef MacinfoDWOSection;
20585ffd83dbSDimitry Andric   StringRef MacroDWOSection;
20590b57cec5SDimitry Andric   StringRef AbbrevDWOSection;
20608bcb0991SDimitry Andric   StringRef StrDWOSection;
20610b57cec5SDimitry Andric   StringRef CUIndexSection;
20620b57cec5SDimitry Andric   StringRef GdbIndexSection;
20630b57cec5SDimitry Andric   StringRef TUIndexSection;
20648bcb0991SDimitry Andric   StringRef LineStrSection;
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric   // A deque holding section data whose iterators are not invalidated when
20670b57cec5SDimitry Andric   // new decompressed sections are inserted at the end.
20680b57cec5SDimitry Andric   std::deque<SmallString<0>> UncompressedSections;
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric   StringRef *mapSectionToMember(StringRef Name) {
20710b57cec5SDimitry Andric     if (DWARFSection *Sec = mapNameToDWARFSection(Name))
20720b57cec5SDimitry Andric       return &Sec->Data;
20730b57cec5SDimitry Andric     return StringSwitch<StringRef *>(Name)
20740b57cec5SDimitry Andric         .Case("debug_abbrev", &AbbrevSection)
20758bcb0991SDimitry Andric         .Case("debug_aranges", &ArangesSection)
20768bcb0991SDimitry Andric         .Case("debug_str", &StrSection)
20770b57cec5SDimitry Andric         .Case("debug_macinfo", &MacinfoSection)
2078480093f4SDimitry Andric         .Case("debug_macinfo.dwo", &MacinfoDWOSection)
20795ffd83dbSDimitry Andric         .Case("debug_macro.dwo", &MacroDWOSection)
20800b57cec5SDimitry Andric         .Case("debug_abbrev.dwo", &AbbrevDWOSection)
20818bcb0991SDimitry Andric         .Case("debug_str.dwo", &StrDWOSection)
20820b57cec5SDimitry Andric         .Case("debug_cu_index", &CUIndexSection)
20830b57cec5SDimitry Andric         .Case("debug_tu_index", &TUIndexSection)
20840b57cec5SDimitry Andric         .Case("gdb_index", &GdbIndexSection)
20858bcb0991SDimitry Andric         .Case("debug_line_str", &LineStrSection)
20860b57cec5SDimitry Andric         // Any more debug info sections go here.
20870b57cec5SDimitry Andric         .Default(nullptr);
20880b57cec5SDimitry Andric   }
20890b57cec5SDimitry Andric 
20900b57cec5SDimitry Andric   /// If Sec is compressed section, decompresses and updates its contents
20910b57cec5SDimitry Andric   /// provided by Data. Otherwise leaves it unchanged.
20920b57cec5SDimitry Andric   Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
20930b57cec5SDimitry Andric                         StringRef &Data) {
2094fcaf7f86SDimitry Andric     if (!Sec.isCompressed())
20950b57cec5SDimitry Andric       return Error::success();
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric     Expected<Decompressor> Decompressor =
20980b57cec5SDimitry Andric         Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
20990b57cec5SDimitry Andric     if (!Decompressor)
21000b57cec5SDimitry Andric       return Decompressor.takeError();
21010b57cec5SDimitry Andric 
21020b57cec5SDimitry Andric     SmallString<0> Out;
21030b57cec5SDimitry Andric     if (auto Err = Decompressor->resizeAndDecompress(Out))
21040b57cec5SDimitry Andric       return Err;
21050b57cec5SDimitry Andric 
21060b57cec5SDimitry Andric     UncompressedSections.push_back(std::move(Out));
21070b57cec5SDimitry Andric     Data = UncompressedSections.back();
21080b57cec5SDimitry Andric 
21090b57cec5SDimitry Andric     return Error::success();
21100b57cec5SDimitry Andric   }
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric public:
21130b57cec5SDimitry Andric   DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
21140b57cec5SDimitry Andric                    uint8_t AddrSize, bool IsLittleEndian)
21150b57cec5SDimitry Andric       : IsLittleEndian(IsLittleEndian) {
21160b57cec5SDimitry Andric     for (const auto &SecIt : Sections) {
21170b57cec5SDimitry Andric       if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
21180b57cec5SDimitry Andric         *SectionData = SecIt.second->getBuffer();
21190b57cec5SDimitry Andric       else if (SecIt.first() == "debug_info")
21200b57cec5SDimitry Andric         // Find debug_info and debug_types data by section rather than name as
21210b57cec5SDimitry Andric         // there are multiple, comdat grouped, of these sections.
21220b57cec5SDimitry Andric         InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
21230b57cec5SDimitry Andric       else if (SecIt.first() == "debug_info.dwo")
21240b57cec5SDimitry Andric         InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
21250b57cec5SDimitry Andric       else if (SecIt.first() == "debug_types")
21260b57cec5SDimitry Andric         TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
21270b57cec5SDimitry Andric       else if (SecIt.first() == "debug_types.dwo")
21280b57cec5SDimitry Andric         TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
21290b57cec5SDimitry Andric     }
21300b57cec5SDimitry Andric   }
21310b57cec5SDimitry Andric   DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
2132349cc55cSDimitry Andric                    function_ref<void(Error)> HandleError,
2133349cc55cSDimitry Andric                    function_ref<void(Error)> HandleWarning,
2134349cc55cSDimitry Andric                    DWARFContext::ProcessDebugRelocations RelocAction)
21350b57cec5SDimitry Andric       : IsLittleEndian(Obj.isLittleEndian()),
21360b57cec5SDimitry Andric         AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
21370b57cec5SDimitry Andric         Obj(&Obj) {
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric     StringMap<unsigned> SectionAmountMap;
21400b57cec5SDimitry Andric     for (const SectionRef &Section : Obj.sections()) {
21410b57cec5SDimitry Andric       StringRef Name;
21428bcb0991SDimitry Andric       if (auto NameOrErr = Section.getName())
21438bcb0991SDimitry Andric         Name = *NameOrErr;
21448bcb0991SDimitry Andric       else
21458bcb0991SDimitry Andric         consumeError(NameOrErr.takeError());
21468bcb0991SDimitry Andric 
21470b57cec5SDimitry Andric       ++SectionAmountMap[Name];
21480b57cec5SDimitry Andric       SectionNames.push_back({ Name, true });
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric       // Skip BSS and Virtual sections, they aren't interesting.
21510b57cec5SDimitry Andric       if (Section.isBSS() || Section.isVirtual())
21520b57cec5SDimitry Andric         continue;
21530b57cec5SDimitry Andric 
21540b57cec5SDimitry Andric       // Skip sections stripped by dsymutil.
21550b57cec5SDimitry Andric       if (Section.isStripped())
21560b57cec5SDimitry Andric         continue;
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric       StringRef Data;
21598bcb0991SDimitry Andric       Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
21608bcb0991SDimitry Andric       if (!SecOrErr) {
21615ffd83dbSDimitry Andric         HandleError(createError("failed to get relocated section: ",
21625ffd83dbSDimitry Andric                                 SecOrErr.takeError()));
21638bcb0991SDimitry Andric         continue;
21648bcb0991SDimitry Andric       }
21658bcb0991SDimitry Andric 
21660b57cec5SDimitry Andric       // Try to obtain an already relocated version of this section.
21670b57cec5SDimitry Andric       // Else use the unrelocated section from the object file. We'll have to
21680b57cec5SDimitry Andric       // apply relocations ourselves later.
2169fe6060f1SDimitry Andric       section_iterator RelocatedSection =
2170fe6060f1SDimitry Andric           Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
21710b57cec5SDimitry Andric       if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
21720b57cec5SDimitry Andric         Expected<StringRef> E = Section.getContents();
21730b57cec5SDimitry Andric         if (E)
21740b57cec5SDimitry Andric           Data = *E;
21750b57cec5SDimitry Andric         else
21760b57cec5SDimitry Andric           // maybeDecompress below will error.
21770b57cec5SDimitry Andric           consumeError(E.takeError());
21780b57cec5SDimitry Andric       }
21790b57cec5SDimitry Andric 
21800b57cec5SDimitry Andric       if (auto Err = maybeDecompress(Section, Name, Data)) {
21815ffd83dbSDimitry Andric         HandleError(createError("failed to decompress '" + Name + "', ",
21825ffd83dbSDimitry Andric                                 std::move(Err)));
21830b57cec5SDimitry Andric         continue;
21840b57cec5SDimitry Andric       }
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric       // Map platform specific debug section names to DWARF standard section
21870b57cec5SDimitry Andric       // names.
218806c3fb27SDimitry Andric       Name = Name.substr(Name.find_first_not_of("._"));
21890b57cec5SDimitry Andric       Name = Obj.mapDebugSectionName(Name);
21900b57cec5SDimitry Andric 
21910b57cec5SDimitry Andric       if (StringRef *SectionData = mapSectionToMember(Name)) {
21920b57cec5SDimitry Andric         *SectionData = Data;
21930b57cec5SDimitry Andric         if (Name == "debug_ranges") {
21940b57cec5SDimitry Andric           // FIXME: Use the other dwo range section when we emit it.
21958bcb0991SDimitry Andric           RangesDWOSection.Data = Data;
2196fe6060f1SDimitry Andric         } else if (Name == "debug_frame" || Name == "eh_frame") {
2197fe6060f1SDimitry Andric           if (DWARFSection *S = mapNameToDWARFSection(Name))
2198fe6060f1SDimitry Andric             S->Address = Section.getAddress();
21990b57cec5SDimitry Andric         }
2200e8d8bef9SDimitry Andric       } else if (InfoSectionMap *Sections =
2201e8d8bef9SDimitry Andric                      StringSwitch<InfoSectionMap *>(Name)
2202e8d8bef9SDimitry Andric                          .Case("debug_info", &InfoSections)
2203e8d8bef9SDimitry Andric                          .Case("debug_info.dwo", &InfoDWOSections)
2204e8d8bef9SDimitry Andric                          .Case("debug_types", &TypesSections)
2205e8d8bef9SDimitry Andric                          .Case("debug_types.dwo", &TypesDWOSections)
2206e8d8bef9SDimitry Andric                          .Default(nullptr)) {
22070b57cec5SDimitry Andric         // Find debug_info and debug_types data by section rather than name as
22080b57cec5SDimitry Andric         // there are multiple, comdat grouped, of these sections.
2209e8d8bef9SDimitry Andric         DWARFSectionMap &S = (*Sections)[Section];
2210e8d8bef9SDimitry Andric         S.Data = Data;
22110b57cec5SDimitry Andric       }
22120b57cec5SDimitry Andric 
2213349cc55cSDimitry Andric       if (RelocatedSection == Obj.section_end() ||
2214349cc55cSDimitry Andric           (RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
22150b57cec5SDimitry Andric         continue;
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric       StringRef RelSecName;
22188bcb0991SDimitry Andric       if (auto NameOrErr = RelocatedSection->getName())
22198bcb0991SDimitry Andric         RelSecName = *NameOrErr;
22208bcb0991SDimitry Andric       else
22218bcb0991SDimitry Andric         consumeError(NameOrErr.takeError());
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric       // If the section we're relocating was relocated already by the JIT,
22240b57cec5SDimitry Andric       // then we used the relocated version above, so we do not need to process
22250b57cec5SDimitry Andric       // relocations for it now.
22268bcb0991SDimitry Andric       StringRef RelSecData;
22270b57cec5SDimitry Andric       if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
22280b57cec5SDimitry Andric         continue;
22290b57cec5SDimitry Andric 
22300b57cec5SDimitry Andric       // In Mach-o files, the relocations do not need to be applied if
22310b57cec5SDimitry Andric       // there is no load offset to apply. The value read at the
22320b57cec5SDimitry Andric       // relocation point already factors in the section address
22330b57cec5SDimitry Andric       // (actually applying the relocations will produce wrong results
22340b57cec5SDimitry Andric       // as the section address will be added twice).
22350b57cec5SDimitry Andric       if (!L && isa<MachOObjectFile>(&Obj))
22360b57cec5SDimitry Andric         continue;
22370b57cec5SDimitry Andric 
223806c3fb27SDimitry Andric       if (!Section.relocations().empty() && Name.ends_with(".dwo") &&
22395f757f3fSDimitry Andric           RelSecName.starts_with(".debug")) {
224006c3fb27SDimitry Andric         HandleWarning(createError("unexpected relocations for dwo section '" +
224106c3fb27SDimitry Andric                                   RelSecName + "'"));
224206c3fb27SDimitry Andric       }
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric       // TODO: Add support for relocations in other sections as needed.
22450b57cec5SDimitry Andric       // Record relocations for the debug_info and debug_line sections.
224606c3fb27SDimitry Andric       RelSecName = RelSecName.substr(RelSecName.find_first_not_of("._"));
22470b57cec5SDimitry Andric       DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
22480b57cec5SDimitry Andric       RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
22490b57cec5SDimitry Andric       if (!Map) {
22500b57cec5SDimitry Andric         // Find debug_info and debug_types relocs by section rather than name
22510b57cec5SDimitry Andric         // as there are multiple, comdat grouped, of these sections.
22520b57cec5SDimitry Andric         if (RelSecName == "debug_info")
22530b57cec5SDimitry Andric           Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
22540b57cec5SDimitry Andric                      .Relocs;
22550b57cec5SDimitry Andric         else if (RelSecName == "debug_types")
22560b57cec5SDimitry Andric           Map =
22570b57cec5SDimitry Andric               &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
22580b57cec5SDimitry Andric                    .Relocs;
22590b57cec5SDimitry Andric         else
22600b57cec5SDimitry Andric           continue;
22610b57cec5SDimitry Andric       }
22620b57cec5SDimitry Andric 
22630b57cec5SDimitry Andric       if (Section.relocation_begin() == Section.relocation_end())
22640b57cec5SDimitry Andric         continue;
22650b57cec5SDimitry Andric 
22660b57cec5SDimitry Andric       // Symbol to [address, section index] cache mapping.
22670b57cec5SDimitry Andric       std::map<SymbolRef, SymInfo> AddrCache;
2268e8d8bef9SDimitry Andric       SupportsRelocation Supports;
22690b57cec5SDimitry Andric       RelocationResolver Resolver;
22700b57cec5SDimitry Andric       std::tie(Supports, Resolver) = getRelocationResolver(Obj);
22710b57cec5SDimitry Andric       for (const RelocationRef &Reloc : Section.relocations()) {
22720b57cec5SDimitry Andric         // FIXME: it's not clear how to correctly handle scattered
22730b57cec5SDimitry Andric         // relocations.
22740b57cec5SDimitry Andric         if (isRelocScattered(Obj, Reloc))
22750b57cec5SDimitry Andric           continue;
22760b57cec5SDimitry Andric 
22770b57cec5SDimitry Andric         Expected<SymInfo> SymInfoOrErr =
22780b57cec5SDimitry Andric             getSymbolInfo(Obj, Reloc, L, AddrCache);
22790b57cec5SDimitry Andric         if (!SymInfoOrErr) {
22805ffd83dbSDimitry Andric           HandleError(SymInfoOrErr.takeError());
22810b57cec5SDimitry Andric           continue;
22820b57cec5SDimitry Andric         }
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric         // Check if Resolver can handle this relocation type early so as not to
22850b57cec5SDimitry Andric         // handle invalid cases in DWARFDataExtractor.
22860b57cec5SDimitry Andric         //
22870b57cec5SDimitry Andric         // TODO Don't store Resolver in every RelocAddrEntry.
22880b57cec5SDimitry Andric         if (Supports && Supports(Reloc.getType())) {
22890b57cec5SDimitry Andric           auto I = Map->try_emplace(
22900b57cec5SDimitry Andric               Reloc.getOffset(),
2291bdd1243dSDimitry Andric               RelocAddrEntry{
2292bdd1243dSDimitry Andric                   SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address,
2293bdd1243dSDimitry Andric                   std::optional<object::RelocationRef>(), 0, Resolver});
22940b57cec5SDimitry Andric           // If we didn't successfully insert that's because we already had a
22950b57cec5SDimitry Andric           // relocation for that offset. Store it as a second relocation in the
22960b57cec5SDimitry Andric           // same RelocAddrEntry instead.
22970b57cec5SDimitry Andric           if (!I.second) {
22980b57cec5SDimitry Andric             RelocAddrEntry &entry = I.first->getSecond();
22990b57cec5SDimitry Andric             if (entry.Reloc2) {
23005ffd83dbSDimitry Andric               HandleError(createError(
23010b57cec5SDimitry Andric                   "At most two relocations per offset are supported"));
23020b57cec5SDimitry Andric             }
23030b57cec5SDimitry Andric             entry.Reloc2 = Reloc;
23040b57cec5SDimitry Andric             entry.SymbolValue2 = SymInfoOrErr->Address;
23050b57cec5SDimitry Andric           }
23060b57cec5SDimitry Andric         } else {
23070b57cec5SDimitry Andric           SmallString<32> Type;
23080b57cec5SDimitry Andric           Reloc.getTypeName(Type);
23095ffd83dbSDimitry Andric           // FIXME: Support more relocations & change this to an error
23105ffd83dbSDimitry Andric           HandleWarning(
23110b57cec5SDimitry Andric               createError("failed to compute relocation: " + Type + ", ",
23120b57cec5SDimitry Andric                           errorCodeToError(object_error::parse_failed)));
23130b57cec5SDimitry Andric         }
23140b57cec5SDimitry Andric       }
23150b57cec5SDimitry Andric     }
23160b57cec5SDimitry Andric 
23170b57cec5SDimitry Andric     for (SectionName &S : SectionNames)
23180b57cec5SDimitry Andric       if (SectionAmountMap[S.Name] > 1)
23190b57cec5SDimitry Andric         S.IsNameUnique = false;
23200b57cec5SDimitry Andric   }
23210b57cec5SDimitry Andric 
2322bdd1243dSDimitry Andric   std::optional<RelocAddrEntry> find(const DWARFSection &S,
23230b57cec5SDimitry Andric                                      uint64_t Pos) const override {
23240b57cec5SDimitry Andric     auto &Sec = static_cast<const DWARFSectionMap &>(S);
23250b57cec5SDimitry Andric     RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
23260b57cec5SDimitry Andric     if (AI == Sec.Relocs.end())
2327bdd1243dSDimitry Andric       return std::nullopt;
23280b57cec5SDimitry Andric     return AI->second;
23290b57cec5SDimitry Andric   }
23300b57cec5SDimitry Andric 
23310b57cec5SDimitry Andric   const object::ObjectFile *getFile() const override { return Obj; }
23320b57cec5SDimitry Andric 
23330b57cec5SDimitry Andric   ArrayRef<SectionName> getSectionNames() const override {
23340b57cec5SDimitry Andric     return SectionNames;
23350b57cec5SDimitry Andric   }
23360b57cec5SDimitry Andric 
23370b57cec5SDimitry Andric   bool isLittleEndian() const override { return IsLittleEndian; }
23380b57cec5SDimitry Andric   StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
23390b57cec5SDimitry Andric   const DWARFSection &getLineDWOSection() const override {
23400b57cec5SDimitry Andric     return LineDWOSection;
23410b57cec5SDimitry Andric   }
23420b57cec5SDimitry Andric   const DWARFSection &getLocDWOSection() const override {
23430b57cec5SDimitry Andric     return LocDWOSection;
23440b57cec5SDimitry Andric   }
23458bcb0991SDimitry Andric   StringRef getStrDWOSection() const override { return StrDWOSection; }
23468bcb0991SDimitry Andric   const DWARFSection &getStrOffsetsDWOSection() const override {
23478bcb0991SDimitry Andric     return StrOffsetsDWOSection;
23480b57cec5SDimitry Andric   }
23498bcb0991SDimitry Andric   const DWARFSection &getRangesDWOSection() const override {
23508bcb0991SDimitry Andric     return RangesDWOSection;
23510b57cec5SDimitry Andric   }
23520b57cec5SDimitry Andric   const DWARFSection &getRnglistsDWOSection() const override {
23530b57cec5SDimitry Andric     return RnglistsDWOSection;
23540b57cec5SDimitry Andric   }
2355480093f4SDimitry Andric   const DWARFSection &getLoclistsDWOSection() const override {
2356480093f4SDimitry Andric     return LoclistsDWOSection;
2357480093f4SDimitry Andric   }
23580b57cec5SDimitry Andric   const DWARFSection &getAddrSection() const override { return AddrSection; }
23590b57cec5SDimitry Andric   StringRef getCUIndexSection() const override { return CUIndexSection; }
23600b57cec5SDimitry Andric   StringRef getGdbIndexSection() const override { return GdbIndexSection; }
23610b57cec5SDimitry Andric   StringRef getTUIndexSection() const override { return TUIndexSection; }
23620b57cec5SDimitry Andric 
23630b57cec5SDimitry Andric   // DWARF v5
23648bcb0991SDimitry Andric   const DWARFSection &getStrOffsetsSection() const override {
23658bcb0991SDimitry Andric     return StrOffsetsSection;
23660b57cec5SDimitry Andric   }
23678bcb0991SDimitry Andric   StringRef getLineStrSection() const override { return LineStrSection; }
23680b57cec5SDimitry Andric 
23690b57cec5SDimitry Andric   // Sections for DWARF5 split dwarf proposal.
23700b57cec5SDimitry Andric   void forEachInfoDWOSections(
23710b57cec5SDimitry Andric       function_ref<void(const DWARFSection &)> F) const override {
23720b57cec5SDimitry Andric     for (auto &P : InfoDWOSections)
23730b57cec5SDimitry Andric       F(P.second);
23740b57cec5SDimitry Andric   }
23750b57cec5SDimitry Andric   void forEachTypesDWOSections(
23760b57cec5SDimitry Andric       function_ref<void(const DWARFSection &)> F) const override {
23770b57cec5SDimitry Andric     for (auto &P : TypesDWOSections)
23780b57cec5SDimitry Andric       F(P.second);
23790b57cec5SDimitry Andric   }
23800b57cec5SDimitry Andric 
23810b57cec5SDimitry Andric   StringRef getAbbrevSection() const override { return AbbrevSection; }
23820b57cec5SDimitry Andric   const DWARFSection &getLocSection() const override { return LocSection; }
23838bcb0991SDimitry Andric   const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
23848bcb0991SDimitry Andric   StringRef getArangesSection() const override { return ArangesSection; }
23858bcb0991SDimitry Andric   const DWARFSection &getFrameSection() const override {
23868bcb0991SDimitry Andric     return FrameSection;
23870b57cec5SDimitry Andric   }
23880b57cec5SDimitry Andric   const DWARFSection &getEHFrameSection() const override {
23890b57cec5SDimitry Andric     return EHFrameSection;
23900b57cec5SDimitry Andric   }
23910b57cec5SDimitry Andric   const DWARFSection &getLineSection() const override { return LineSection; }
23928bcb0991SDimitry Andric   StringRef getStrSection() const override { return StrSection; }
23938bcb0991SDimitry Andric   const DWARFSection &getRangesSection() const override { return RangesSection; }
23940b57cec5SDimitry Andric   const DWARFSection &getRnglistsSection() const override {
23950b57cec5SDimitry Andric     return RnglistsSection;
23960b57cec5SDimitry Andric   }
23975ffd83dbSDimitry Andric   const DWARFSection &getMacroSection() const override { return MacroSection; }
23985ffd83dbSDimitry Andric   StringRef getMacroDWOSection() const override { return MacroDWOSection; }
23990b57cec5SDimitry Andric   StringRef getMacinfoSection() const override { return MacinfoSection; }
2400480093f4SDimitry Andric   StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
24018bcb0991SDimitry Andric   const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
24028bcb0991SDimitry Andric   const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
24038bcb0991SDimitry Andric   const DWARFSection &getGnuPubnamesSection() const override {
24048bcb0991SDimitry Andric     return GnuPubnamesSection;
24050b57cec5SDimitry Andric   }
24068bcb0991SDimitry Andric   const DWARFSection &getGnuPubtypesSection() const override {
24078bcb0991SDimitry Andric     return GnuPubtypesSection;
24080b57cec5SDimitry Andric   }
24090b57cec5SDimitry Andric   const DWARFSection &getAppleNamesSection() const override {
24100b57cec5SDimitry Andric     return AppleNamesSection;
24110b57cec5SDimitry Andric   }
24120b57cec5SDimitry Andric   const DWARFSection &getAppleTypesSection() const override {
24130b57cec5SDimitry Andric     return AppleTypesSection;
24140b57cec5SDimitry Andric   }
24150b57cec5SDimitry Andric   const DWARFSection &getAppleNamespacesSection() const override {
24160b57cec5SDimitry Andric     return AppleNamespacesSection;
24170b57cec5SDimitry Andric   }
24180b57cec5SDimitry Andric   const DWARFSection &getAppleObjCSection() const override {
24190b57cec5SDimitry Andric     return AppleObjCSection;
24200b57cec5SDimitry Andric   }
24218bcb0991SDimitry Andric   const DWARFSection &getNamesSection() const override {
24228bcb0991SDimitry Andric     return NamesSection;
24230b57cec5SDimitry Andric   }
24240b57cec5SDimitry Andric 
24250b57cec5SDimitry Andric   StringRef getFileName() const override { return FileName; }
24260b57cec5SDimitry Andric   uint8_t getAddressSize() const override { return AddressSize; }
24270b57cec5SDimitry Andric   void forEachInfoSections(
24280b57cec5SDimitry Andric       function_ref<void(const DWARFSection &)> F) const override {
24290b57cec5SDimitry Andric     for (auto &P : InfoSections)
24300b57cec5SDimitry Andric       F(P.second);
24310b57cec5SDimitry Andric   }
24320b57cec5SDimitry Andric   void forEachTypesSections(
24330b57cec5SDimitry Andric       function_ref<void(const DWARFSection &)> F) const override {
24340b57cec5SDimitry Andric     for (auto &P : TypesSections)
24350b57cec5SDimitry Andric       F(P.second);
24360b57cec5SDimitry Andric   }
24370b57cec5SDimitry Andric };
24380b57cec5SDimitry Andric } // namespace
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric std::unique_ptr<DWARFContext>
2441349cc55cSDimitry Andric DWARFContext::create(const object::ObjectFile &Obj,
2442349cc55cSDimitry Andric                      ProcessDebugRelocations RelocAction,
2443349cc55cSDimitry Andric                      const LoadedObjectInfo *L, std::string DWPName,
24445ffd83dbSDimitry Andric                      std::function<void(Error)> RecoverableErrorHandler,
24455f757f3fSDimitry Andric                      std::function<void(Error)> WarningHandler,
24465f757f3fSDimitry Andric                      bool ThreadSafe) {
2447349cc55cSDimitry Andric   auto DObj = std::make_unique<DWARFObjInMemory>(
2448349cc55cSDimitry Andric       Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
24495f757f3fSDimitry Andric   return std::make_unique<DWARFContext>(std::move(DObj),
24505f757f3fSDimitry Andric                                         std::move(DWPName),
24515ffd83dbSDimitry Andric                                         RecoverableErrorHandler,
24525f757f3fSDimitry Andric                                         WarningHandler,
24535f757f3fSDimitry Andric                                         ThreadSafe);
24540b57cec5SDimitry Andric }
24550b57cec5SDimitry Andric 
24560b57cec5SDimitry Andric std::unique_ptr<DWARFContext>
24570b57cec5SDimitry Andric DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
24585ffd83dbSDimitry Andric                      uint8_t AddrSize, bool isLittleEndian,
24595ffd83dbSDimitry Andric                      std::function<void(Error)> RecoverableErrorHandler,
24605f757f3fSDimitry Andric                      std::function<void(Error)> WarningHandler,
24615f757f3fSDimitry Andric                      bool ThreadSafe) {
24620b57cec5SDimitry Andric   auto DObj =
24638bcb0991SDimitry Andric       std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
24645ffd83dbSDimitry Andric   return std::make_unique<DWARFContext>(
24655f757f3fSDimitry Andric       std::move(DObj), "", RecoverableErrorHandler, WarningHandler, ThreadSafe);
24660b57cec5SDimitry Andric }
24670b57cec5SDimitry Andric 
24680b57cec5SDimitry Andric uint8_t DWARFContext::getCUAddrSize() {
24690b57cec5SDimitry Andric   // In theory, different compile units may have different address byte
24700b57cec5SDimitry Andric   // sizes, but for simplicity we just use the address byte size of the
24715ffd83dbSDimitry Andric   // first compile unit. In practice the address size field is repeated across
24720b57cec5SDimitry Andric   // various DWARF headers (at least in version 5) to make it easier to dump
24730b57cec5SDimitry Andric   // them independently, not to enable varying the address size.
2474e8d8bef9SDimitry Andric   auto CUs = compile_units();
24755ffd83dbSDimitry Andric   return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
24760b57cec5SDimitry Andric }
2477