LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFContext.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 713 736 96.9 %
Date: 2017-09-14 15:23:50 Functions: 87 87 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFContext.cpp ---------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      11             : #include "llvm/ADT/STLExtras.h"
      12             : #include "llvm/ADT/SmallString.h"
      13             : #include "llvm/ADT/SmallVector.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/ADT/StringSwitch.h"
      16             : #include "llvm/BinaryFormat/Dwarf.h"
      17             : #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
      18             : #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
      19             : #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
      20             : #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
      21             : #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
      22             : #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
      23             : #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
      24             : #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
      25             : #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
      26             : #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
      27             : #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
      28             : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
      29             : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
      30             : #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
      31             : #include "llvm/DebugInfo/DWARF/DWARFSection.h"
      32             : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
      33             : #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
      34             : #include "llvm/MC/MCRegisterInfo.h"
      35             : #include "llvm/Object/Decompressor.h"
      36             : #include "llvm/Object/MachO.h"
      37             : #include "llvm/Object/ObjectFile.h"
      38             : #include "llvm/Object/RelocVisitor.h"
      39             : #include "llvm/Support/Casting.h"
      40             : #include "llvm/Support/DataExtractor.h"
      41             : #include "llvm/Support/Error.h"
      42             : #include "llvm/Support/Format.h"
      43             : #include "llvm/Support/MemoryBuffer.h"
      44             : #include "llvm/Support/TargetRegistry.h"
      45             : #include "llvm/Support/raw_ostream.h"
      46             : #include <algorithm>
      47             : #include <cstdint>
      48             : #include <map>
      49             : #include <string>
      50             : #include <tuple>
      51             : #include <utility>
      52             : #include <vector>
      53             : 
      54             : using namespace llvm;
      55             : using namespace dwarf;
      56             : using namespace object;
      57             : 
      58             : #define DEBUG_TYPE "dwarf"
      59             : 
      60             : using DWARFLineTable = DWARFDebugLine::LineTable;
      61             : using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
      62             : using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
      63             : 
      64        1008 : DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
      65        1008 :                            std::string DWPName)
      66       23184 :     : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {}
      67             : 
      68             : DWARFContext::~DWARFContext() = default;
      69             : 
      70         665 : static void dumpAccelSection(raw_ostream &OS, StringRef Name,
      71             :                              const DWARFObject &Obj,
      72             :                              const DWARFSection &Section,
      73             :                              StringRef StringSection, bool LittleEndian) {
      74        1330 :   DWARFDataExtractor AccelSection(Obj, Section, LittleEndian, 0);
      75        1330 :   DataExtractor StrData(StringSection, LittleEndian, 0);
      76         665 :   OS << "\n." << Name << " contents:\n";
      77         739 :   DWARFAcceleratorTable Accel(AccelSection, StrData);
      78         665 :   if (!Accel.extract())
      79         591 :     return;
      80          74 :   Accel.dump(OS);
      81             : }
      82             : 
      83             : /// Dump the UUID load command.
      84         169 : static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
      85          60 :   auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
      86             :   if (!MachO)
      87             :     return;
      88         368 :   for (auto LC : MachO->load_commands()) {
      89             :     raw_ostream::uuid_t UUID;
      90         308 :     if (LC.C.cmd == MachO::LC_UUID) {
      91          23 :       if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
      92           0 :         OS << "error: UUID load command is too short.\n";
      93           0 :         return;
      94             :       }
      95          23 :       OS << "UUID: ";
      96          23 :       memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
      97          23 :       OS.write_uuid(UUID);
      98          23 :       OS << ' ' << MachO->getFileFormatName();
      99          23 :       OS << ' ' << MachO->getFileName() << '\n';
     100             :     }
     101             :   }
     102             : }
     103             : 
     104             : static void
     105           9 : dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
     106             :                                 const DWARFObject &Obj,
     107             :                                 const DWARFSection &StringOffsetsSection,
     108             :                                 StringRef StringSection, bool LittleEndian) {
     109          18 :   DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
     110           9 :   uint32_t Offset = 0;
     111           9 :   uint64_t SectionSize = StringOffsetsSection.Data.size();
     112             : 
     113          35 :   while (Offset < SectionSize) {
     114          18 :     unsigned Version = 0;
     115          18 :     DwarfFormat Format = DWARF32;
     116          18 :     unsigned EntrySize = 4;
     117             :     // Perform validation and extract the segment size from the header.
     118          35 :     if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
     119           1 :       OS << "error: invalid contribution to string offsets table in section ."
     120           1 :          << SectionName << ".\n";
     121           1 :       return;
     122             :     }
     123          17 :     uint32_t ContributionStart = Offset;
     124          17 :     uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
     125             :     // A contribution size of 0xffffffff indicates DWARF64, with the actual size
     126             :     // in the following 8 bytes. Otherwise, the DWARF standard mandates that
     127             :     // the contribution size must be at most 0xfffffff0.
     128          17 :     if (ContributionSize == 0xffffffff) {
     129           1 :       if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
     130           1 :         OS << "error: invalid contribution to string offsets table in section ."
     131           1 :            << SectionName << ".\n";
     132           1 :         return;
     133             :       }
     134           0 :       Format = DWARF64;
     135           0 :       EntrySize = 8;
     136           0 :       ContributionSize = StrOffsetExt.getU64(&Offset);
     137          16 :     } else if (ContributionSize > 0xfffffff0) {
     138           1 :       OS << "error: invalid contribution to string offsets table in section ."
     139           1 :          << SectionName << ".\n";
     140           1 :       return;
     141             :     }
     142             : 
     143             :     // We must ensure that we don't read a partial record at the end, so we
     144             :     // validate for a multiple of EntrySize. Also, we're expecting a version
     145             :     // number and padding, which adds an additional 4 bytes.
     146          15 :     uint64_t ValidationSize =
     147          15 :         4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
     148          28 :     if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
     149           2 :       OS << "error: contribution to string offsets table in section ."
     150           2 :          << SectionName << " has invalid length.\n";
     151           2 :       return;
     152             :     }
     153             : 
     154          13 :     Version = StrOffsetExt.getU16(&Offset);
     155          13 :     Offset += 2;
     156          26 :     OS << format("0x%8.8x: ", ContributionStart);
     157          13 :     OS << "Contribution size = " << ContributionSize
     158          26 :        << ", Version = " << Version << "\n";
     159             : 
     160          13 :     uint32_t ContributionBase = Offset;
     161          13 :     DataExtractor StrData(StringSection, LittleEndian, 0);
     162          39 :     while (Offset - ContributionBase < ContributionSize) {
     163          78 :       OS << format("0x%8.8x: ", Offset);
     164             :       // FIXME: We can only extract strings in DWARF32 format at the moment.
     165             :       uint64_t StringOffset =
     166          39 :           StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
     167          39 :       if (Format == DWARF32) {
     168          39 :         uint32_t StringOffset32 = (uint32_t)StringOffset;
     169          78 :         OS << format("%8.8x ", StringOffset32);
     170          39 :         const char *S = StrData.getCStr(&StringOffset32);
     171          39 :         if (S)
     172          39 :           OS << format("\"%s\"", S);
     173             :       } else
     174           0 :         OS << format("%16.16" PRIx64 " ", StringOffset);
     175          39 :       OS << "\n";
     176             :     }
     177             :   }
     178             : }
     179             : 
     180             : // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
     181             : // string offsets section, where each compile or type unit contributes a
     182             : // number of entries (string offsets), with each contribution preceded by
     183             : // a header containing size and version number. Alternatively, it may be a
     184             : // monolithic series of string offsets, as generated by the pre-DWARF v5
     185             : // implementation of split DWARF.
     186         332 : static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
     187             :                                      const DWARFObject &Obj,
     188             :                                      const DWARFSection &StringOffsetsSection,
     189             :                                      StringRef StringSection, bool LittleEndian,
     190             :                                      unsigned MaxVersion) {
     191         664 :   if (StringOffsetsSection.Data.empty())
     192             :     return;
     193          28 :   OS << "\n." << SectionName << " contents:\n";
     194             :   // If we have at least one (compile or type) unit with DWARF v5 or greater,
     195             :   // we assume that the section is formatted like a DWARF v5 string offsets
     196             :   // section.
     197          28 :   if (MaxVersion >= 5)
     198           9 :     dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
     199             :                                     StringSection, LittleEndian);
     200             :   else {
     201          38 :     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
     202          19 :     uint32_t offset = 0;
     203          19 :     uint64_t size = StringOffsetsSection.Data.size();
     204             :     // Ensure that size is a multiple of the size of an entry.
     205          19 :     if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
     206           1 :       OS << "error: size of ." << SectionName << " is not a multiple of "
     207           1 :          << sizeof(uint32_t) << ".\n";
     208           1 :       size &= -(uint64_t)sizeof(uint32_t);
     209             :     }
     210          19 :     DataExtractor StrData(StringSection, LittleEndian, 0);
     211         473 :     while (offset < size) {
     212         454 :       OS << format("0x%8.8x: ", offset);
     213         227 :       uint32_t StringOffset = strOffsetExt.getU32(&offset);
     214         454 :       OS << format("%8.8x  ", StringOffset);
     215         227 :       const char *S = StrData.getCStr(&StringOffset);
     216         227 :       if (S)
     217         227 :         OS << format("\"%s\"", S);
     218         227 :       OS << "\n";
     219             :     }
     220             :   }
     221             : }
     222             : 
     223         478 : void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
     224         478 :   uint64_t DumpType = DumpOpts.DumpType;
     225         478 :   bool DumpEH = DumpOpts.DumpEH;
     226             : 
     227         956 :   const auto *ObjFile = DObj->getFile();
     228         478 :   if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
     229         475 :     outs() << ObjFile->getFileName() << ":\tfile format "
     230         475 :            << ObjFile->getFileFormatName() << "\n\n";
     231         478 :   if (DumpType & DIDT_UUID)
     232         169 :     dumpUUID(OS, *ObjFile);
     233             : 
     234         478 :   if (DumpType & DIDT_DebugAbbrev) {
     235         170 :     OS << ".debug_abbrev contents:\n";
     236         170 :     getDebugAbbrev()->dump(OS);
     237             :   }
     238             : 
     239         478 :   if (DumpType & DIDT_DebugAbbrevDwo)
     240         166 :     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
     241         166 :       OS << "\n.debug_abbrev.dwo contents:\n";
     242         166 :       D->dump(OS);
     243             :     }
     244             : 
     245         478 :   if (DumpType & DIDT_DebugInfo) {
     246         408 :     OS << "\n.debug_info contents:\n";
     247         875 :     for (const auto &CU : compile_units())
     248         467 :       CU->dump(OS, DumpOpts);
     249             :   }
     250             : 
     251         646 :   if ((DumpType & DIDT_DebugInfoDwo) &&
     252         168 :       getNumDWOCompileUnits()) {
     253          24 :     OS << "\n.debug_info.dwo contents:\n";
     254          61 :     for (const auto &DWOCU : dwo_compile_units())
     255          37 :       DWOCU->dump(OS, DumpOpts);
     256             :   }
     257             : 
     258         478 :   if ((DumpType & DIDT_DebugTypes) && getNumTypeUnits()) {
     259          12 :     OS << "\n.debug_types contents:\n";
     260          63 :     for (const auto &TUS : type_unit_sections())
     261         108 :       for (const auto &TU : TUS)
     262          27 :         TU->dump(OS, DumpOpts);
     263             :   }
     264             : 
     265         644 :   if ((DumpType & DIDT_DebugTypesDwo) &&
     266         166 :       getNumDWOTypeUnits()) {
     267          12 :     OS << "\n.debug_types.dwo contents:\n";
     268          48 :     for (const auto &DWOTUS : dwo_type_unit_sections())
     269          59 :       for (const auto &DWOTU : DWOTUS)
     270          23 :         DWOTU->dump(OS, DumpOpts);
     271             :   }
     272             : 
     273         478 :   if (DumpType & DIDT_DebugLoc) {
     274         174 :     OS << "\n.debug_loc contents:\n";
     275         348 :     getDebugLoc()->dump(OS, getRegisterInfo());
     276             :   }
     277             : 
     278         478 :   if (DumpType & DIDT_DebugLocDwo) {
     279         166 :     OS << "\n.debug_loc.dwo contents:\n";
     280         332 :     getDebugLocDWO()->dump(OS, getRegisterInfo());
     281             :   }
     282             : 
     283         478 :   if (DumpType & DIDT_DebugFrames) {
     284         179 :     OS << "\n.debug_frame contents:\n";
     285         179 :     getDebugFrame()->dump(OS);
     286         179 :     if (DumpEH) {
     287           9 :       OS << "\n.eh_frame contents:\n";
     288           9 :       getEHFrame()->dump(OS);
     289             :     }
     290             :   }
     291             : 
     292         478 :   if (DumpType & DIDT_DebugMacro) {
     293         167 :     OS << "\n.debug_macinfo contents:\n";
     294         167 :     getDebugMacro()->dump(OS);
     295             :   }
     296             : 
     297         478 :   uint32_t offset = 0;
     298         478 :   if (DumpType & DIDT_DebugAranges) {
     299         167 :     OS << "\n.debug_aranges contents:\n";
     300         501 :     DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
     301         167 :     DWARFDebugArangeSet set;
     302         315 :     while (set.extract(arangesData, &offset))
     303          74 :       set.dump(OS);
     304             :   }
     305             : 
     306         478 :   uint8_t savedAddressByteSize = 0;
     307         478 :   if (DumpType & DIDT_DebugLine) {
     308         185 :     OS << "\n.debug_line contents:\n";
     309         414 :     for (const auto &CU : compile_units()) {
     310         229 :       savedAddressByteSize = CU->getAddressByteSize();
     311         458 :       auto CUDIE = CU->getUnitDIE();
     312         229 :       if (!CUDIE)
     313           1 :         continue;
     314         912 :       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
     315         880 :         DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
     316         880 :                                     isLittleEndian(), savedAddressByteSize);
     317         440 :         DWARFDebugLine::LineTable LineTable;
     318         220 :         uint32_t Offset = *StmtOffset;
     319         220 :         LineTable.parse(lineData, &Offset);
     320         220 :         LineTable.dump(OS);
     321             :       }
     322             :     }
     323             :   }
     324             : 
     325         478 :   if (DumpType & DIDT_DebugCUIndex) {
     326         166 :     OS << "\n.debug_cu_index contents:\n";
     327         166 :     getCUIndex().dump(OS);
     328             :   }
     329             : 
     330         478 :   if (DumpType & DIDT_DebugTUIndex) {
     331         166 :     OS << "\n.debug_tu_index contents:\n";
     332         166 :     getTUIndex().dump(OS);
     333             :   }
     334             : 
     335         478 :   if (DumpType & DIDT_DebugLineDwo) {
     336         166 :     OS << "\n.debug_line.dwo contents:\n";
     337         166 :     unsigned stmtOffset = 0;
     338         664 :     DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
     339         664 :                                 isLittleEndian(), savedAddressByteSize);
     340         332 :     DWARFDebugLine::LineTable LineTable;
     341         226 :     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
     342          30 :       LineTable.dump(OS);
     343          30 :       LineTable.clear();
     344             :     }
     345             :   }
     346             : 
     347         478 :   if (DumpType & DIDT_DebugStr) {
     348         169 :     OS << "\n.debug_str contents:\n";
     349         507 :     DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
     350         169 :     offset = 0;
     351         169 :     uint32_t strOffset = 0;
     352        1783 :     while (const char *s = strData.getCStr(&offset)) {
     353        3228 :       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
     354        1614 :       strOffset = offset;
     355        1614 :     }
     356             :   }
     357             : 
     358         644 :   if ((DumpType & DIDT_DebugStrDwo) &&
     359         953 :       !DObj->getStringDWOSection().empty()) {
     360          23 :     OS << "\n.debug_str.dwo contents:\n";
     361          69 :     DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
     362          23 :     offset = 0;
     363          23 :     uint32_t strDWOOffset = 0;
     364         266 :     while (const char *s = strDWOData.getCStr(&offset)) {
     365         486 :       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
     366         243 :       strDWOOffset = offset;
     367         243 :     }
     368             :   }
     369             : 
     370         478 :   if (DumpType & DIDT_DebugRanges) {
     371         168 :     OS << "\n.debug_ranges contents:\n";
     372             :     // In fact, different compile units may have different address byte
     373             :     // sizes, but for simplicity we just use the address byte size of the last
     374             :     // compile unit (there is no easy and fast way to associate address range
     375             :     // list and the compile unit it describes).
     376         672 :     DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
     377         672 :                                   isLittleEndian(), savedAddressByteSize);
     378         168 :     offset = 0;
     379         168 :     DWARFDebugRangeList rangeList;
     380         230 :     while (rangeList.extract(rangesData, &offset))
     381          31 :       rangeList.dump(OS);
     382             :   }
     383             : 
     384         478 :   if (DumpType & DIDT_DebugPubnames)
     385         513 :     DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
     386         171 :         .dump("debug_pubnames", OS);
     387             : 
     388         478 :   if (DumpType & DIDT_DebugPubtypes)
     389         498 :     DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
     390         166 :         .dump("debug_pubtypes", OS);
     391             : 
     392         478 :   if (DumpType & DIDT_DebugGnuPubnames)
     393         498 :     DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
     394             :                        true /* GnuStyle */)
     395         166 :         .dump("debug_gnu_pubnames", OS);
     396             : 
     397         478 :   if (DumpType & DIDT_DebugGnuPubtypes)
     398         498 :     DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
     399             :                        true /* GnuStyle */)
     400         166 :         .dump("debug_gnu_pubtypes", OS);
     401             : 
     402         478 :   if (DumpType & DIDT_DebugStrOffsets)
     403         830 :     dumpStringOffsetsSection(
     404         664 :         OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
     405         498 :         DObj->getStringSection(), isLittleEndian(), getMaxVersion());
     406             : 
     407         478 :   if (DumpType & DIDT_DebugStrOffsetsDwo) {
     408         830 :     dumpStringOffsetsSection(
     409         664 :         OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
     410         498 :         DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
     411             :   }
     412             : 
     413         651 :   if ((DumpType & DIDT_GdbIndex) &&
     414         990 :       !DObj->getGdbIndexSection().empty()) {
     415           7 :     OS << "\n.gnu_index contents:\n";
     416           7 :     getGdbIndex().dump(OS);
     417             :   }
     418             : 
     419         478 :   if (DumpType & DIDT_AppleNames)
     420         835 :     dumpAccelSection(OS, "apple_names", *DObj, DObj->getAppleNamesSection(),
     421         501 :                      DObj->getStringSection(), isLittleEndian());
     422             : 
     423         478 :   if (DumpType & DIDT_AppleTypes)
     424         830 :     dumpAccelSection(OS, "apple_types", *DObj, DObj->getAppleTypesSection(),
     425         498 :                      DObj->getStringSection(), isLittleEndian());
     426             : 
     427         478 :   if (DumpType & DIDT_AppleNamespaces)
     428         830 :     dumpAccelSection(OS, "apple_namespaces", *DObj,
     429         332 :                      DObj->getAppleNamespacesSection(),
     430         498 :                      DObj->getStringSection(), isLittleEndian());
     431             : 
     432         478 :   if (DumpType & DIDT_AppleObjC)
     433         830 :     dumpAccelSection(OS, "apple_objc", *DObj, DObj->getAppleObjCSection(),
     434         498 :                      DObj->getStringSection(), isLittleEndian());
     435         478 : }
     436             : 
     437          17 : DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
     438          17 :   parseDWOCompileUnits();
     439             : 
     440          17 :   if (const auto &CUI = getCUIndex()) {
     441           4 :     if (const auto *R = CUI.getFromHash(Hash))
     442           4 :       if (auto CUOff = R->getOffset(DW_SECT_INFO))
     443           4 :         return DWOCUs.getUnitForOffset(CUOff->Offset);
     444             :     return nullptr;
     445             :   }
     446             : 
     447             :   // If there's no index, just search through the CUs in the DWO - there's
     448             :   // probably only one unless this is something like LTO - though an in-process
     449             :   // built/cached lookup table could be used in that case to improve repeated
     450             :   // lookups of different CUs in the DWO.
     451          16 :   for (const auto &DWOCU : dwo_compile_units())
     452          35 :     if (DWOCU->getDWOId() == Hash)
     453          13 :       return DWOCU.get();
     454             :   return nullptr;
     455             : }
     456             : 
     457         109 : DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
     458         109 :   parseCompileUnits();
     459         109 :   if (auto *CU = CUs.getUnitForOffset(Offset))
     460         108 :     return CU->getDIEForOffset(Offset);
     461           1 :   return DWARFDie();
     462             : }
     463             : 
     464          21 : bool DWARFContext::verify(raw_ostream &OS, uint64_t DumpType,
     465             :                           DIDumpOptions DumpOpts) {
     466          21 :   bool Success = true;
     467          42 :   DWARFVerifier verifier(OS, *this, DumpOpts);
     468             : 
     469          21 :   Success &= verifier.handleDebugAbbrev();
     470          21 :   if (DumpType & DIDT_DebugInfo)
     471          21 :     Success &= verifier.handleDebugInfo();
     472          21 :   if (DumpType & DIDT_DebugLine)
     473          12 :     Success &= verifier.handleDebugLine();
     474          21 :   Success &= verifier.handleAccelTables();
     475          42 :   return Success;
     476             : }
     477             : 
     478        1188 : const DWARFUnitIndex &DWARFContext::getCUIndex() {
     479        2376 :   if (CUIndex)
     480             :     return *CUIndex;
     481             : 
     482        2517 :   DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
     483             : 
     484        1678 :   CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
     485        1678 :   CUIndex->parse(CUIndexData);
     486        1678 :   return *CUIndex;
     487             : }
     488             : 
     489         205 : const DWARFUnitIndex &DWARFContext::getTUIndex() {
     490         410 :   if (TUIndex)
     491             :     return *TUIndex;
     492             : 
     493         501 :   DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
     494             : 
     495         334 :   TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
     496         334 :   TUIndex->parse(TUIndexData);
     497         334 :   return *TUIndex;
     498             : }
     499             : 
     500           7 : DWARFGdbIndex &DWARFContext::getGdbIndex() {
     501          14 :   if (GdbIndex)
     502             :     return *GdbIndex;
     503             : 
     504          21 :   DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
     505           7 :   GdbIndex = llvm::make_unique<DWARFGdbIndex>();
     506          14 :   GdbIndex->parse(GdbIndexData);
     507          14 :   return *GdbIndex;
     508             : }
     509             : 
     510        2786 : const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
     511        5572 :   if (Abbrev)
     512             :     return Abbrev.get();
     513             : 
     514        2481 :   DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
     515             : 
     516        1654 :   Abbrev.reset(new DWARFDebugAbbrev());
     517        1654 :   Abbrev->extract(abbrData);
     518        1654 :   return Abbrev.get();
     519             : }
     520             : 
     521         401 : const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
     522         802 :   if (AbbrevDWO)
     523             :     return AbbrevDWO.get();
     524             : 
     525         558 :   DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
     526         372 :   AbbrevDWO.reset(new DWARFDebugAbbrev());
     527         372 :   AbbrevDWO->extract(abbrData);
     528         372 :   return AbbrevDWO.get();
     529             : }
     530             : 
     531         174 : const DWARFDebugLoc *DWARFContext::getDebugLoc() {
     532         348 :   if (Loc)
     533             :     return Loc.get();
     534             : 
     535         522 :   Loc.reset(new DWARFDebugLoc);
     536             :   // assume all compile units have the same address byte size
     537         174 :   if (getNumCompileUnits()) {
     538         628 :     DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
     539         471 :                                getCompileUnitAtIndex(0)->getAddressByteSize());
     540         314 :     Loc->parse(LocData);
     541             :   }
     542         348 :   return Loc.get();
     543             : }
     544             : 
     545         166 : const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
     546         332 :   if (LocDWO)
     547             :     return LocDWO.get();
     548             : 
     549         498 :   DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0);
     550         498 :   LocDWO.reset(new DWARFDebugLocDWO());
     551         332 :   LocDWO->parse(LocData);
     552         332 :   return LocDWO.get();
     553             : }
     554             : 
     555         992 : const DWARFDebugAranges *DWARFContext::getDebugAranges() {
     556        1984 :   if (Aranges)
     557             :     return Aranges.get();
     558             : 
     559         519 :   Aranges.reset(new DWARFDebugAranges());
     560         346 :   Aranges->generate(this);
     561         346 :   return Aranges.get();
     562             : }
     563             : 
     564         179 : const DWARFDebugFrame *DWARFContext::getDebugFrame() {
     565         358 :   if (DebugFrame)
     566             :     return DebugFrame.get();
     567             : 
     568             :   // There's a "bug" in the DWARFv3 standard with respect to the target address
     569             :   // size within debug frame sections. While DWARF is supposed to be independent
     570             :   // of its container, FDEs have fields with size being "target address size",
     571             :   // which isn't specified in DWARF in general. It's only specified for CUs, but
     572             :   // .eh_frame can appear without a .debug_info section. Follow the example of
     573             :   // other tools (libdwarf) and extract this from the container (ObjectFile
     574             :   // provides this information). This problem is fixed in DWARFv4
     575             :   // See this dwarf-discuss discussion for more details:
     576             :   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
     577         358 :   DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
     578         716 :                                DObj->getAddressSize());
     579         358 :   DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
     580         358 :   DebugFrame->parse(debugFrameData);
     581         358 :   return DebugFrame.get();
     582             : }
     583             : 
     584           9 : const DWARFDebugFrame *DWARFContext::getEHFrame() {
     585          18 :   if (EHFrame)
     586             :     return EHFrame.get();
     587             : 
     588          18 :   DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
     589          36 :                                DObj->getAddressSize());
     590          18 :   DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
     591          18 :   DebugFrame->parse(debugFrameData);
     592          18 :   return DebugFrame.get();
     593             : }
     594             : 
     595         167 : const DWARFDebugMacro *DWARFContext::getDebugMacro() {
     596         334 :   if (Macro)
     597             :     return Macro.get();
     598             : 
     599         501 :   DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
     600         501 :   Macro.reset(new DWARFDebugMacro());
     601         334 :   Macro->parse(MacinfoData);
     602         334 :   return Macro.get();
     603             : }
     604             : 
     605             : const DWARFLineTable *
     606        3408 : DWARFContext::getLineTableForUnit(DWARFUnit *U) {
     607        6816 :   if (!Line)
     608        1052 :     Line.reset(new DWARFDebugLine);
     609             : 
     610        3408 :   auto UnitDIE = U->getUnitDIE();
     611        3408 :   if (!UnitDIE)
     612             :     return nullptr;
     613             : 
     614       10224 :   auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
     615        3408 :   if (!Offset)
     616             :     return nullptr; // No line table for this compile unit.
     617             : 
     618        6550 :   uint32_t stmtOffset = *Offset + U->getLineTableOffset();
     619             :   // See if the line table is cached.
     620        6550 :   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
     621             :     return lt;
     622             : 
     623             :   // Make sure the offset is good before we try to parse.
     624        1446 :   if (stmtOffset >= U->getLineSection().Data.size())
     625             :     return nullptr;
     626             : 
     627             :   // We have to parse it first.
     628        2163 :   DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
     629        2163 :                               U->getAddressByteSize());
     630        1442 :   return Line->getOrParseLineTable(lineData, stmtOffset);
     631             : }
     632             : 
     633        2498 : void DWARFContext::parseCompileUnits() {
     634        4996 :   CUs.parse(*this, DObj->getInfoSection());
     635        2498 : }
     636             : 
     637         180 : void DWARFContext::parseTypeUnits() {
     638         360 :   if (!TUs.empty())
     639             :     return;
     640         699 :   DObj->forEachTypesSections([&](const DWARFSection &S) {
     641          27 :     TUs.emplace_back();
     642          54 :     TUs.back().parse(*this, S);
     643         195 :   });
     644             : }
     645             : 
     646         222 : void DWARFContext::parseDWOCompileUnits() {
     647         444 :   DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
     648         222 : }
     649             : 
     650         178 : void DWARFContext::parseDWOTypeUnits() {
     651         356 :   if (!DWOTUs.empty())
     652             :     return;
     653         676 :   DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
     654          12 :     DWOTUs.emplace_back();
     655          24 :     DWOTUs.back().parseDWO(*this, S);
     656         178 :   });
     657             : }
     658             : 
     659         992 : DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
     660         992 :   parseCompileUnits();
     661         992 :   return CUs.getUnitForOffset(Offset);
     662             : }
     663             : 
     664         992 : DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
     665             :   // First, get the offset of the compile unit.
     666         992 :   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
     667             :   // Retrieve the compile unit.
     668         992 :   return getCompileUnitForOffset(CUOffset);
     669             : }
     670             : 
     671         424 : static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
     672             :                                                   uint64_t Address,
     673             :                                                   FunctionNameKind Kind,
     674             :                                                   std::string &FunctionName,
     675             :                                                   uint32_t &StartLine) {
     676             :   // The address may correspond to instruction in some inlined function,
     677             :   // so we have to build the chain of inlined functions and take the
     678             :   // name of the topmost function in it.
     679         848 :   SmallVector<DWARFDie, 4> InlinedChain;
     680         424 :   CU->getInlinedChainForAddress(Address, InlinedChain);
     681         424 :   if (InlinedChain.empty())
     682             :     return false;
     683             : 
     684         419 :   const DWARFDie &DIE = InlinedChain[0];
     685         419 :   bool FoundResult = false;
     686         419 :   const char *Name = nullptr;
     687         419 :   if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
     688         271 :     FunctionName = Name;
     689         271 :     FoundResult = true;
     690             :   }
     691         419 :   if (auto DeclLineResult = DIE.getDeclLine()) {
     692         419 :     StartLine = DeclLineResult;
     693         419 :     FoundResult = true;
     694             :   }
     695             : 
     696             :   return FoundResult;
     697             : }
     698             : 
     699         415 : DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
     700             :                                                DILineInfoSpecifier Spec) {
     701         415 :   DILineInfo Result;
     702             : 
     703         415 :   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
     704         415 :   if (!CU)
     705             :     return Result;
     706         398 :   getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
     707             :                                         Result.FunctionName,
     708             :                                         Result.StartLine);
     709         398 :   if (Spec.FLIKind != FileLineInfoKind::None) {
     710         398 :     if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
     711         398 :       LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
     712             :                                            Spec.FLIKind, Result);
     713             :   }
     714             :   return Result;
     715             : }
     716             : 
     717             : DILineInfoTable
     718          26 : DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
     719             :                                          DILineInfoSpecifier Spec) {
     720          26 :   DILineInfoTable  Lines;
     721          26 :   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
     722          26 :   if (!CU)
     723             :     return Lines;
     724             : 
     725          52 :   std::string FunctionName = "<invalid>";
     726          26 :   uint32_t StartLine = 0;
     727          26 :   getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
     728             :                                         StartLine);
     729             : 
     730             :   // If the Specifier says we don't need FileLineInfo, just
     731             :   // return the top-most function at the starting address.
     732          26 :   if (Spec.FLIKind == FileLineInfoKind::None) {
     733           0 :     DILineInfo Result;
     734           0 :     Result.FunctionName = FunctionName;
     735           0 :     Result.StartLine = StartLine;
     736           0 :     Lines.push_back(std::make_pair(Address, Result));
     737             :     return Lines;
     738             :   }
     739             : 
     740          26 :   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
     741             : 
     742             :   // Get the index of row we're looking for in the line table.
     743          26 :   std::vector<uint32_t> RowVector;
     744          26 :   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
     745             :     return Lines;
     746             : 
     747         220 :   for (uint32_t RowIndex : RowVector) {
     748             :     // Take file number and line/column from the row.
     749         232 :     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
     750         232 :     DILineInfo Result;
     751         116 :     LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
     752             :                                   Spec.FLIKind, Result.FileName);
     753         116 :     Result.FunctionName = FunctionName;
     754         116 :     Result.Line = Row.Line;
     755         116 :     Result.Column = Row.Column;
     756         116 :     Result.StartLine = StartLine;
     757         348 :     Lines.push_back(std::make_pair(Row.Address, Result));
     758             :   }
     759             : 
     760             :   return Lines;
     761             : }
     762             : 
     763             : DIInliningInfo
     764         551 : DWARFContext::getInliningInfoForAddress(uint64_t Address,
     765             :                                         DILineInfoSpecifier Spec) {
     766         551 :   DIInliningInfo InliningInfo;
     767             : 
     768         551 :   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
     769         551 :   if (!CU)
     770             :     return InliningInfo;
     771             : 
     772         494 :   const DWARFLineTable *LineTable = nullptr;
     773         494 :   SmallVector<DWARFDie, 4> InlinedChain;
     774         494 :   CU->getInlinedChainForAddress(Address, InlinedChain);
     775         494 :   if (InlinedChain.size() == 0) {
     776             :     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
     777             :     // try to at least get file/line info from symbol table.
     778          11 :     if (Spec.FLIKind != FileLineInfoKind::None) {
     779          22 :       DILineInfo Frame;
     780          11 :       LineTable = getLineTableForUnit(CU);
     781          22 :       if (LineTable &&
     782          11 :           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
     783             :                                                Spec.FLIKind, Frame))
     784             :         InliningInfo.addFrame(Frame);
     785             :     }
     786             :     return InliningInfo;
     787             :   }
     788             : 
     789         483 :   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
     790        1588 :   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
     791        1244 :     DWARFDie &FunctionDIE = InlinedChain[i];
     792        1244 :     DILineInfo Frame;
     793             :     // Get function name if necessary.
     794         622 :     if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
     795             :       Frame.FunctionName = Name;
     796         622 :     if (auto DeclLineResult = FunctionDIE.getDeclLine())
     797         589 :       Frame.StartLine = DeclLineResult;
     798         622 :     if (Spec.FLIKind != FileLineInfoKind::None) {
     799         622 :       if (i == 0) {
     800             :         // For the topmost frame, initialize the line table of this
     801             :         // compile unit and fetch file/line info from it.
     802         483 :         LineTable = getLineTableForUnit(CU);
     803             :         // For the topmost routine, get file/line info from line table.
     804         483 :         if (LineTable)
     805         483 :           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
     806             :                                                Spec.FLIKind, Frame);
     807             :       } else {
     808             :         // Otherwise, use call file, call line and call column from
     809             :         // previous DIE in inlined chain.
     810         139 :         if (LineTable)
     811         139 :           LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
     812             :                                         Spec.FLIKind, Frame.FileName);
     813         139 :         Frame.Line = CallLine;
     814         139 :         Frame.Column = CallColumn;
     815         139 :         Frame.Discriminator = CallDiscriminator;
     816             :       }
     817             :       // Get call file/line/column of a current DIE.
     818         622 :       if (i + 1 < n) {
     819         139 :         FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
     820             :                                    CallDiscriminator);
     821             :       }
     822             :     }
     823         622 :     InliningInfo.addFrame(Frame);
     824             :   }
     825             :   return InliningInfo;
     826             : }
     827             : 
     828             : std::shared_ptr<DWARFContext>
     829          29 : DWARFContext::getDWOContext(StringRef AbsolutePath) {
     830          87 :   if (auto S = DWP.lock()) {
     831           0 :     DWARFContext *Ctxt = S->Context.get();
     832           0 :     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
     833             :   }
     834             : 
     835          58 :   std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
     836             : 
     837          87 :   if (auto S = Entry->lock()) {
     838           0 :     DWARFContext *Ctxt = S->Context.get();
     839           0 :     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
     840             :   }
     841             : 
     842          29 :   Expected<OwningBinary<ObjectFile>> Obj = [&] {
     843          51 :     if (!CheckedForDWP) {
     844          40 :       SmallString<128> DWPName;
     845             :       auto Obj = object::ObjectFile::createObjectFile(
     846          44 :           this->DWPName.empty()
     847          85 :               ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
     848          62 :               : StringRef(this->DWPName));
     849          22 :       if (Obj) {
     850           4 :         Entry = &DWP;
     851           4 :         return Obj;
     852             :       } else {
     853          18 :         CheckedForDWP = true;
     854             :         // TODO: Should this error be handled (maybe in a high verbosity mode)
     855             :         // before falling back to .dwo files?
     856          36 :         consumeError(Obj.takeError());
     857             :       }
     858             :     }
     859             : 
     860          25 :     return object::ObjectFile::createObjectFile(AbsolutePath);
     861          58 :   }();
     862             : 
     863          29 :   if (!Obj) {
     864             :     // TODO: Actually report errors helpfully.
     865          24 :     consumeError(Obj.takeError());
     866             :     return nullptr;
     867             :   }
     868             : 
     869          17 :   auto S = std::make_shared<DWOFile>();
     870          34 :   S->File = std::move(Obj.get());
     871         153 :   S->Context = DWARFContext::create(*S->File.getBinary());
     872          34 :   *Entry = S;
     873          34 :   auto *Ctxt = S->Context.get();
     874          34 :   return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
     875             : }
     876             : 
     877          15 : static Error createError(const Twine &Reason, llvm::Error E) {
     878         105 :   return make_error<StringError>(Reason + toString(std::move(E)),
     879          45 :                                  inconvertibleErrorCode());
     880             : }
     881             : 
     882             : /// SymInfo contains information about symbol: it's address
     883             : /// and section index which is -1LL for absolute symbols.
     884             : struct SymInfo {
     885             :   uint64_t Address;
     886             :   uint64_t SectionIndex;
     887             : };
     888             : 
     889             : /// Returns the address of symbol relocation used against and a section index.
     890             : /// Used for futher relocations computation. Symbol's section load address is
     891        4560 : static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
     892             :                                        const RelocationRef &Reloc,
     893             :                                        const LoadedObjectInfo *L,
     894             :                                        std::map<SymbolRef, SymInfo> &Cache) {
     895        4560 :   SymInfo Ret = {0, (uint64_t)-1LL};
     896        4560 :   object::section_iterator RSec = Obj.section_end();
     897        4560 :   object::symbol_iterator Sym = Reloc.getSymbol();
     898             : 
     899        4560 :   std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
     900             :   // First calculate the address of the symbol or section as it appears
     901             :   // in the object file
     902        9120 :   if (Sym != Obj.symbol_end()) {
     903             :     bool New;
     904       22600 :     std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
     905        4520 :     if (!New)
     906        5490 :       return CacheIt->second;
     907             : 
     908        5325 :     Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
     909        1775 :     if (!SymAddrOrErr)
     910           0 :       return createError("failed to compute symbol address: ",
     911           0 :                          SymAddrOrErr.takeError());
     912             : 
     913             :     // Also remember what section this symbol is in for later
     914        5325 :     auto SectOrErr = Sym->getSection();
     915        1775 :     if (!SectOrErr)
     916           0 :       return createError("failed to get symbol section: ",
     917           0 :                          SectOrErr.takeError());
     918             : 
     919        1775 :     RSec = *SectOrErr;
     920        1775 :     Ret.Address = *SymAddrOrErr;
     921          13 :   } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
     922          26 :     RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
     923          26 :     Ret.Address = RSec->getAddress();
     924             :   }
     925             : 
     926        3630 :   if (RSec != Obj.section_end())
     927        3512 :     Ret.SectionIndex = RSec->getIndex();
     928             : 
     929             :   // If we are given load addresses for the sections, we need to adjust:
     930             :   // SymAddr = (Address of Symbol Or Section in File) -
     931             :   //           (Address of Section in File) +
     932             :   //           (Load Address of Section)
     933             :   // RSec is now either the section being targeted or the section
     934             :   // containing the symbol being targeted. In either case,
     935             :   // we need to perform the same computation.
     936        1842 :   if (L && RSec != Obj.section_end())
     937          27 :     if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
     938          42 :       Ret.Address += SectionLoadAddress - RSec->getAddress();
     939             : 
     940        3630 :   if (CacheIt != Cache.end())
     941        1775 :     CacheIt->second = Ret;
     942             : 
     943             :   return Ret;
     944             : }
     945             : 
     946        4560 : static bool isRelocScattered(const object::ObjectFile &Obj,
     947             :                              const RelocationRef &Reloc) {
     948          13 :   const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
     949             :   if (!MachObj)
     950             :     return false;
     951             :   // MachO also has relocations that point to sections and
     952             :   // scattered relocations.
     953          26 :   auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
     954          13 :   return MachObj->isRelocationScattered(RelocInfo);
     955             : }
     956             : 
     957          12 : ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
     958          84 :   errs() << "error: " + toString(std::move(E)) << '\n';
     959          12 :   return ErrorPolicy::Continue;
     960             : }
     961             : 
     962             : namespace {
     963       66565 : struct DWARFSectionMap final : public DWARFSection {
     964             :   RelocAddrMap Relocs;
     965             : };
     966             : 
     967       18459 : class DWARFObjInMemory final : public DWARFObject {
     968             :   bool IsLittleEndian;
     969             :   uint8_t AddressSize;
     970             :   StringRef FileName;
     971             :   const object::ObjectFile *Obj = nullptr;
     972             :   std::vector<SectionName> SectionNames;
     973             : 
     974             :   using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
     975             :                                    std::map<object::SectionRef, unsigned>>;
     976             : 
     977             :   TypeSectionMap TypesSections;
     978             :   TypeSectionMap TypesDWOSections;
     979             : 
     980             :   DWARFSectionMap InfoSection;
     981             :   DWARFSectionMap LocSection;
     982             :   DWARFSectionMap LineSection;
     983             :   DWARFSectionMap RangeSection;
     984             :   DWARFSectionMap StringOffsetSection;
     985             :   DWARFSectionMap InfoDWOSection;
     986             :   DWARFSectionMap LineDWOSection;
     987             :   DWARFSectionMap LocDWOSection;
     988             :   DWARFSectionMap StringOffsetDWOSection;
     989             :   DWARFSectionMap RangeDWOSection;
     990             :   DWARFSectionMap AddrSection;
     991             :   DWARFSectionMap AppleNamesSection;
     992             :   DWARFSectionMap AppleTypesSection;
     993             :   DWARFSectionMap AppleNamespacesSection;
     994             :   DWARFSectionMap AppleObjCSection;
     995             : 
     996       17033 :   DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
     997       17033 :     return StringSwitch<DWARFSectionMap *>(Name)
     998       51099 :         .Case("debug_info", &InfoSection)
     999       51099 :         .Case("debug_loc", &LocSection)
    1000       51099 :         .Case("debug_line", &LineSection)
    1001       51099 :         .Case("debug_str_offsets", &StringOffsetSection)
    1002       51099 :         .Case("debug_ranges", &RangeSection)
    1003       51099 :         .Case("debug_info.dwo", &InfoDWOSection)
    1004       51099 :         .Case("debug_loc.dwo", &LocDWOSection)
    1005       51099 :         .Case("debug_line.dwo", &LineDWOSection)
    1006       51099 :         .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
    1007       51099 :         .Case("debug_addr", &AddrSection)
    1008       51099 :         .Case("apple_names", &AppleNamesSection)
    1009       51099 :         .Case("apple_types", &AppleTypesSection)
    1010       51099 :         .Case("apple_namespaces", &AppleNamespacesSection)
    1011       51099 :         .Case("apple_namespac", &AppleNamespacesSection)
    1012       51099 :         .Case("apple_objc", &AppleObjCSection)
    1013       51099 :         .Default(nullptr);
    1014             :   }
    1015             : 
    1016             :   StringRef AbbrevSection;
    1017             :   StringRef ARangeSection;
    1018             :   StringRef DebugFrameSection;
    1019             :   StringRef EHFrameSection;
    1020             :   StringRef StringSection;
    1021             :   StringRef MacinfoSection;
    1022             :   StringRef PubNamesSection;
    1023             :   StringRef PubTypesSection;
    1024             :   StringRef GnuPubNamesSection;
    1025             :   StringRef AbbrevDWOSection;
    1026             :   StringRef StringDWOSection;
    1027             :   StringRef GnuPubTypesSection;
    1028             :   StringRef CUIndexSection;
    1029             :   StringRef GdbIndexSection;
    1030             :   StringRef TUIndexSection;
    1031             : 
    1032             :   SmallVector<SmallString<32>, 4> UncompressedSections;
    1033             : 
    1034       15564 :   StringRef *mapSectionToMember(StringRef Name) {
    1035       15564 :     if (DWARFSection *Sec = mapNameToDWARFSection(Name))
    1036        3673 :       return &Sec->Data;
    1037       11891 :     return StringSwitch<StringRef *>(Name)
    1038       35673 :         .Case("debug_abbrev", &AbbrevSection)
    1039       35673 :         .Case("debug_aranges", &ARangeSection)
    1040       35673 :         .Case("debug_frame", &DebugFrameSection)
    1041       35673 :         .Case("eh_frame", &EHFrameSection)
    1042       35673 :         .Case("debug_str", &StringSection)
    1043       35673 :         .Case("debug_macinfo", &MacinfoSection)
    1044       35673 :         .Case("debug_pubnames", &PubNamesSection)
    1045       35673 :         .Case("debug_pubtypes", &PubTypesSection)
    1046       35673 :         .Case("debug_gnu_pubnames", &GnuPubNamesSection)
    1047       35673 :         .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
    1048       35673 :         .Case("debug_abbrev.dwo", &AbbrevDWOSection)
    1049       35673 :         .Case("debug_str.dwo", &StringDWOSection)
    1050       35673 :         .Case("debug_cu_index", &CUIndexSection)
    1051       35673 :         .Case("debug_tu_index", &TUIndexSection)
    1052       35673 :         .Case("gdb_index", &GdbIndexSection)
    1053             :         // Any more debug info sections go here.
    1054       23782 :         .Default(nullptr);
    1055             :   }
    1056             : 
    1057             :   /// If Sec is compressed section, decompresses and updates its contents
    1058             :   /// provided by Data. Otherwise leaves it unchanged.
    1059       15529 :   Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
    1060             :                         StringRef &Data) {
    1061       15529 :     if (!Decompressor::isCompressed(Sec))
    1062       46473 :       return Error::success();
    1063             : 
    1064             :     Expected<Decompressor> Decompressor =
    1065          38 :         Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
    1066          38 :     if (!Decompressor)
    1067             :       return Decompressor.takeError();
    1068             : 
    1069          34 :     SmallString<32> Out;
    1070         101 :     if (auto Err = Decompressor->resizeAndDecompress(Out))
    1071           2 :       return Err;
    1072             : 
    1073          33 :     UncompressedSections.emplace_back(std::move(Out));
    1074          99 :     Data = UncompressedSections.back();
    1075             : 
    1076          99 :     return Error::success();
    1077             :   }
    1078             : 
    1079             : public:
    1080          12 :   DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
    1081             :                    uint8_t AddrSize, bool IsLittleEndian)
    1082         444 :       : IsLittleEndian(IsLittleEndian) {
    1083         128 :     for (const auto &SecIt : Sections) {
    1084          40 :       if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
    1085         120 :         *SectionData = SecIt.second->getBuffer();
    1086             :     }
    1087          12 :   }
    1088         868 :   DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
    1089             :                    function_ref<ErrorPolicy(Error)> HandleError)
    1090        1736 :       : IsLittleEndian(Obj.isLittleEndian()),
    1091        1736 :         AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
    1092       33852 :         Obj(&Obj) {
    1093             : 
    1094        1734 :     StringMap<unsigned> SectionAmountMap;
    1095       19333 :     for (const SectionRef &Section : Obj.sections()) {
    1096       15863 :       StringRef Name;
    1097       15863 :       Section.getName(Name);
    1098       15863 :       ++SectionAmountMap[Name];
    1099       31726 :       SectionNames.push_back({ Name, true });
    1100             : 
    1101             :       // Skip BSS and Virtual sections, they aren't interesting.
    1102       31392 :       if (Section.isBSS() || Section.isVirtual())
    1103       15606 :         continue;
    1104             : 
    1105       15529 :       StringRef Data;
    1106       15529 :       section_iterator RelocatedSection = Section.getRelocatedSection();
    1107             :       // Try to obtain an already relocated version of this section.
    1108             :       // Else use the unrelocated section from the object file. We'll have to
    1109             :       // apply relocations ourselves later.
    1110       15529 :       if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
    1111             :         Section.getContents(Data);
    1112             : 
    1113       46582 :       if (auto Err = maybeDecompress(Section, Name, Data)) {
    1114          20 :         ErrorPolicy EP = HandleError(createError(
    1115          30 :             "failed to decompress '" + Name + "', ", std::move(Err)));
    1116           5 :         if (EP == ErrorPolicy::Halt)
    1117           1 :           return;
    1118           8 :         continue;
    1119             :       }
    1120             : 
    1121             :       // Compressed sections names in GNU style starts from ".z",
    1122             :       // at this point section is decompressed and we drop compression prefix.
    1123       15524 :       Name = Name.substr(
    1124       31048 :           Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
    1125             : 
    1126             :       // Map platform specific debug section names to DWARF standard section
    1127             :       // names.
    1128       15524 :       Name = Obj.mapDebugSectionName(Name);
    1129             : 
    1130       15524 :       if (StringRef *SectionData = mapSectionToMember(Name)) {
    1131        7106 :         *SectionData = Data;
    1132        7703 :         if (Name == "debug_ranges") {
    1133             :           // FIXME: Use the other dwo range section when we emit it.
    1134         597 :           RangeDWOSection.Data = Data;
    1135             :         }
    1136        8445 :       } else if (Name == "debug_types") {
    1137             :         // Find debug_types data by section rather than name as there are
    1138             :         // multiple, comdat grouped, debug_types sections.
    1139          27 :         TypesSections[Section].Data = Data;
    1140        8403 :       } else if (Name == "debug_types.dwo") {
    1141          12 :         TypesDWOSections[Section].Data = Data;
    1142             :       }
    1143             : 
    1144       31048 :       if (RelocatedSection == Obj.section_end())
    1145        9772 :         continue;
    1146             : 
    1147        5752 :       StringRef RelSecName;
    1148        5752 :       StringRef RelSecData;
    1149       11504 :       RelocatedSection->getName(RelSecName);
    1150             : 
    1151             :       // If the section we're relocating was relocated already by the JIT,
    1152             :       // then we used the relocated version above, so we do not need to process
    1153             :       // relocations for it now.
    1154        5752 :       if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
    1155           0 :         continue;
    1156             : 
    1157             :       // In Mach-o files, the relocations do not need to be applied if
    1158             :       // there is no load offset to apply. The value read at the
    1159             :       // relocation point already factors in the section address
    1160             :       // (actually applying the relocations will produce wrong results
    1161             :       // as the section address will be added twice).
    1162       21445 :       if (!L && isa<MachOObjectFile>(&Obj))
    1163        4283 :         continue;
    1164             : 
    1165        1469 :       RelSecName = RelSecName.substr(
    1166        2938 :           RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
    1167             : 
    1168             :       // TODO: Add support for relocations in other sections as needed.
    1169             :       // Record relocations for the debug_info and debug_line sections.
    1170        1469 :       DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
    1171        1469 :       RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
    1172             :       if (!Map) {
    1173             :         // Find debug_types relocs by section rather than name as there are
    1174             :         // multiple, comdat grouped, debug_types sections.
    1175         895 :         if (RelSecName == "debug_types")
    1176          26 :           Map =
    1177          26 :               &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
    1178             :                    .Relocs;
    1179        1686 :         else if (RelSecName == "debug_types.dwo")
    1180           3 :           Map = &static_cast<DWARFSectionMap &>(
    1181           3 :                      TypesDWOSections[*RelocatedSection])
    1182             :                      .Relocs;
    1183             :         else
    1184         840 :           continue;
    1185             :       }
    1186             : 
    1187        1887 :       if (Section.relocation_begin() == Section.relocation_end())
    1188          39 :         continue;
    1189             : 
    1190             :       // Symbol to [address, section index] cache mapping.
    1191        1179 :       std::map<SymbolRef, SymInfo> AddrCache;
    1192        6919 :       for (const RelocationRef &Reloc : Section.relocations()) {
    1193             :         // FIXME: it's not clear how to correctly handle scattered
    1194             :         // relocations.
    1195        4560 :         if (isRelocScattered(Obj, Reloc))
    1196          10 :           continue;
    1197             : 
    1198             :         Expected<SymInfo> SymInfoOrErr =
    1199        9109 :             getSymbolInfo(Obj, Reloc, L, AddrCache);
    1200        4560 :         if (!SymInfoOrErr) {
    1201           0 :           if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
    1202           0 :             return;
    1203           0 :           continue;
    1204             :         }
    1205             : 
    1206        4560 :         object::RelocVisitor V(Obj);
    1207        9120 :         uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
    1208        4559 :         if (V.error()) {
    1209          10 :           SmallString<32> Type;
    1210          10 :           Reloc.getTypeName(Type);
    1211             :           ErrorPolicy EP = HandleError(
    1212          50 :               createError("failed to compute relocation: " + Type + ", ",
    1213          30 :                           errorCodeToError(object_error::parse_failed)));
    1214          10 :           if (EP == ErrorPolicy::Halt)
    1215           0 :             return;
    1216          10 :           continue;
    1217             :         }
    1218        4549 :         RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
    1219       13647 :         Map->insert({Reloc.getOffset(), Rel});
    1220             :       }
    1221             :     }
    1222             : 
    1223       19318 :     for (SectionName &S : SectionNames)
    1224       15854 :       if (SectionAmountMap[S.Name] > 1)
    1225         120 :         S.IsNameUnique = false;
    1226             :   }
    1227             : 
    1228     4181785 :   Optional<RelocAddrEntry> find(const DWARFSection &S,
    1229             :                                 uint64_t Pos) const override {
    1230     4181785 :     auto &Sec = static_cast<const DWARFSectionMap &>(S);
    1231     4181785 :     RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
    1232     8363570 :     if (AI == Sec.Relocs.end())
    1233             :       return None;
    1234        5721 :     return AI->second;
    1235             :   }
    1236             : 
    1237         478 :   const object::ObjectFile *getFile() const override { return Obj; }
    1238             : 
    1239          37 :   ArrayRef<SectionName> getSectionNames() const override {
    1240          74 :     return SectionNames;
    1241             :   }
    1242             : 
    1243       11274 :   bool isLittleEndian() const override { return IsLittleEndian; }
    1244         207 :   StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
    1245         400 :   const DWARFSection &getLineDWOSection() const override {
    1246         400 :     return LineDWOSection;
    1247             :   }
    1248         313 :   const DWARFSection &getLocDWOSection() const override {
    1249         313 :     return LocDWOSection;
    1250             :   }
    1251         589 :   StringRef getStringDWOSection() const override { return StringDWOSection; }
    1252         400 :   const DWARFSection &getStringOffsetDWOSection() const override {
    1253         400 :     return StringOffsetDWOSection;
    1254             :   }
    1255         234 :   const DWARFSection &getRangeDWOSection() const override {
    1256         234 :     return RangeDWOSection;
    1257             :   }
    1258        2741 :   const DWARFSection &getAddrSection() const override { return AddrSection; }
    1259         830 :   StringRef getCUIndexSection() const override { return CUIndexSection; }
    1260         180 :   StringRef getGdbIndexSection() const override { return GdbIndexSection; }
    1261         167 :   StringRef getTUIndexSection() const override { return TUIndexSection; }
    1262             : 
    1263             :   // DWARF v5
    1264        2692 :   const DWARFSection &getStringOffsetSection() const override {
    1265        2692 :     return StringOffsetSection;
    1266             :   }
    1267             : 
    1268             :   // Sections for DWARF5 split dwarf proposal.
    1269         222 :   const DWARFSection &getInfoDWOSection() const override {
    1270         222 :     return InfoDWOSection;
    1271             :   }
    1272         166 :   void forEachTypesDWOSections(
    1273             :       function_ref<void(const DWARFSection &)> F) const override {
    1274         676 :     for (auto &P : TypesDWOSections)
    1275          24 :       F(P.second);
    1276         166 :   }
    1277             : 
    1278         839 :   StringRef getAbbrevSection() const override { return AbbrevSection; }
    1279         320 :   const DWARFSection &getLocSection() const override { return LocSection; }
    1280         372 :   StringRef getARangeSection() const override { return ARangeSection; }
    1281         273 :   StringRef getDebugFrameSection() const override { return DebugFrameSection; }
    1282           9 :   StringRef getEHFrameSection() const override { return EHFrameSection; }
    1283        3000 :   const DWARFSection &getLineSection() const override { return LineSection; }
    1284        3716 :   StringRef getStringSection() const override { return StringSection; }
    1285        2813 :   const DWARFSection &getRangeSection() const override { return RangeSection; }
    1286         167 :   StringRef getMacinfoSection() const override { return MacinfoSection; }
    1287         203 :   StringRef getPubNamesSection() const override { return PubNamesSection; }
    1288         198 :   StringRef getPubTypesSection() const override { return PubTypesSection; }
    1289         198 :   StringRef getGnuPubNamesSection() const override {
    1290         198 :     return GnuPubNamesSection;
    1291             :   }
    1292         198 :   StringRef getGnuPubTypesSection() const override {
    1293         198 :     return GnuPubTypesSection;
    1294             :   }
    1295         192 :   const DWARFSection &getAppleNamesSection() const override {
    1296         192 :     return AppleNamesSection;
    1297             :   }
    1298         189 :   const DWARFSection &getAppleTypesSection() const override {
    1299         189 :     return AppleTypesSection;
    1300             :   }
    1301         188 :   const DWARFSection &getAppleNamespacesSection() const override {
    1302         188 :     return AppleNamespacesSection;
    1303             :   }
    1304         207 :   const DWARFSection &getAppleObjCSection() const override {
    1305         207 :     return AppleObjCSection;
    1306             :   }
    1307             : 
    1308          21 :   StringRef getFileName() const override { return FileName; }
    1309         477 :   uint8_t getAddressSize() const override { return AddressSize; }
    1310        2522 :   const DWARFSection &getInfoSection() const override { return InfoSection; }
    1311         168 :   void forEachTypesSections(
    1312             :       function_ref<void(const DWARFSection &)> F) const override {
    1313         699 :     for (auto &P : TypesSections)
    1314          54 :       F(P.second);
    1315         168 :   }
    1316             : };
    1317             : } // namespace
    1318             : 
    1319             : std::unique_ptr<DWARFContext>
    1320         868 : DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
    1321             :                      function_ref<ErrorPolicy(Error)> HandleError,
    1322             :                      std::string DWPName) {
    1323        1735 :   auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
    1324        1734 :   return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
    1325             : }
    1326             : 
    1327             : std::unique_ptr<DWARFContext>
    1328          12 : DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
    1329             :                      uint8_t AddrSize, bool isLittleEndian) {
    1330             :   auto DObj =
    1331          36 :       llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
    1332          24 :   return llvm::make_unique<DWARFContext>(std::move(DObj), "");
    1333             : }
    1334             : 
    1335         469 : Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
    1336             :   // Detect the architecture from the object file. We usually don't need OS
    1337             :   // info to lookup a target and create register info.
    1338         938 :   Triple TT;
    1339         469 :   TT.setArch(Triple::ArchType(Obj.getArch()));
    1340         469 :   TT.setVendor(Triple::UnknownVendor);
    1341         469 :   TT.setOS(Triple::UnknownOS);
    1342         938 :   std::string TargetLookupError;
    1343             :   const Target *TheTarget =
    1344         469 :       TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
    1345         469 :   if (!TargetLookupError.empty())
    1346           2 :     return make_error<StringError>(TargetLookupError, inconvertibleErrorCode());
    1347        1404 :   RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
    1348        1404 :   return Error::success();
    1349             : }

Generated by: LCOV version 1.13