Home | History | Annotate | Download | only in DebugInfo
      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 "DWARFContext.h"
     11 #include "DWARFDebugArangeSet.h"
     12 
     13 #include "llvm/ADT/SmallString.h"
     14 #include "llvm/ADT/StringSwitch.h"
     15 #include "llvm/Support/Compression.h"
     16 #include "llvm/Support/Dwarf.h"
     17 #include "llvm/Support/Format.h"
     18 #include "llvm/Support/Path.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 #include <algorithm>
     21 using namespace llvm;
     22 using namespace dwarf;
     23 using namespace object;
     24 
     25 #define DEBUG_TYPE "dwarf"
     26 
     27 typedef DWARFDebugLine::LineTable DWARFLineTable;
     28 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
     29 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
     30 
     31 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
     32                            bool LittleEndian, bool GnuStyle) {
     33   OS << "\n." << Name << " contents:\n";
     34   DataExtractor pubNames(Data, LittleEndian, 0);
     35   uint32_t offset = 0;
     36   while (pubNames.isValidOffset(offset)) {
     37     OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
     38     OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
     39     OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
     40     OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
     41     if (GnuStyle)
     42       OS << "Offset     Linkage  Kind     Name\n";
     43     else
     44       OS << "Offset     Name\n";
     45 
     46     while (offset < Data.size()) {
     47       uint32_t dieRef = pubNames.getU32(&offset);
     48       if (dieRef == 0)
     49         break;
     50       OS << format("0x%8.8x ", dieRef);
     51       if (GnuStyle) {
     52         PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
     53         OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
     54            << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
     55            << ' ';
     56       }
     57       OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
     58     }
     59   }
     60 }
     61 
     62 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
     63   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
     64     OS << ".debug_abbrev contents:\n";
     65     getDebugAbbrev()->dump(OS);
     66   }
     67 
     68   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
     69     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
     70       OS << "\n.debug_abbrev.dwo contents:\n";
     71       D->dump(OS);
     72     }
     73 
     74   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
     75     OS << "\n.debug_info contents:\n";
     76     for (const auto &CU : compile_units())
     77       CU->dump(OS);
     78   }
     79 
     80   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
     81       getNumDWOCompileUnits()) {
     82     OS << "\n.debug_info.dwo contents:\n";
     83     for (const auto &DWOCU : dwo_compile_units())
     84       DWOCU->dump(OS);
     85   }
     86 
     87   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
     88     OS << "\n.debug_types contents:\n";
     89     for (const auto &TU : type_units())
     90       TU->dump(OS);
     91   }
     92 
     93   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
     94       getNumDWOTypeUnits()) {
     95     OS << "\n.debug_types.dwo contents:\n";
     96     for (const auto &DWOTU : dwo_type_units())
     97       DWOTU->dump(OS);
     98   }
     99 
    100   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
    101     OS << "\n.debug_loc contents:\n";
    102     getDebugLoc()->dump(OS);
    103   }
    104 
    105   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
    106     OS << "\n.debug_loc.dwo contents:\n";
    107     getDebugLocDWO()->dump(OS);
    108   }
    109 
    110   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
    111     OS << "\n.debug_frame contents:\n";
    112     getDebugFrame()->dump(OS);
    113   }
    114 
    115   uint32_t offset = 0;
    116   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
    117     OS << "\n.debug_aranges contents:\n";
    118     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
    119     DWARFDebugArangeSet set;
    120     while (set.extract(arangesData, &offset))
    121       set.dump(OS);
    122   }
    123 
    124   uint8_t savedAddressByteSize = 0;
    125   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
    126     OS << "\n.debug_line contents:\n";
    127     for (const auto &CU : compile_units()) {
    128       savedAddressByteSize = CU->getAddressByteSize();
    129       unsigned stmtOffset =
    130           CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
    131               CU.get(), DW_AT_stmt_list, -1U);
    132       if (stmtOffset != -1U) {
    133         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
    134                                savedAddressByteSize);
    135         DWARFDebugLine::LineTable LineTable;
    136         LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
    137         LineTable.dump(OS);
    138       }
    139     }
    140   }
    141 
    142   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
    143     OS << "\n.debug_line.dwo contents:\n";
    144     unsigned stmtOffset = 0;
    145     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
    146                            savedAddressByteSize);
    147     DWARFDebugLine::LineTable LineTable;
    148     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
    149       LineTable.dump(OS);
    150       LineTable.clear();
    151     }
    152   }
    153 
    154   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
    155     OS << "\n.debug_str contents:\n";
    156     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
    157     offset = 0;
    158     uint32_t strOffset = 0;
    159     while (const char *s = strData.getCStr(&offset)) {
    160       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
    161       strOffset = offset;
    162     }
    163   }
    164 
    165   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
    166       !getStringDWOSection().empty()) {
    167     OS << "\n.debug_str.dwo contents:\n";
    168     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
    169     offset = 0;
    170     uint32_t strDWOOffset = 0;
    171     while (const char *s = strDWOData.getCStr(&offset)) {
    172       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
    173       strDWOOffset = offset;
    174     }
    175   }
    176 
    177   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
    178     OS << "\n.debug_ranges contents:\n";
    179     // In fact, different compile units may have different address byte
    180     // sizes, but for simplicity we just use the address byte size of the last
    181     // compile unit (there is no easy and fast way to associate address range
    182     // list and the compile unit it describes).
    183     DataExtractor rangesData(getRangeSection(), isLittleEndian(),
    184                              savedAddressByteSize);
    185     offset = 0;
    186     DWARFDebugRangeList rangeList;
    187     while (rangeList.extract(rangesData, &offset))
    188       rangeList.dump(OS);
    189   }
    190 
    191   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
    192     dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
    193                    isLittleEndian(), false);
    194 
    195   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
    196     dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
    197                    isLittleEndian(), false);
    198 
    199   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
    200     dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
    201                    isLittleEndian(), true /* GnuStyle */);
    202 
    203   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
    204     dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
    205                    isLittleEndian(), true /* GnuStyle */);
    206 
    207   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
    208       !getStringOffsetDWOSection().empty()) {
    209     OS << "\n.debug_str_offsets.dwo contents:\n";
    210     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
    211                                0);
    212     offset = 0;
    213     uint64_t size = getStringOffsetDWOSection().size();
    214     while (offset < size) {
    215       OS << format("0x%8.8x: ", offset);
    216       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
    217     }
    218   }
    219 }
    220 
    221 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
    222   if (Abbrev)
    223     return Abbrev.get();
    224 
    225   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
    226 
    227   Abbrev.reset(new DWARFDebugAbbrev());
    228   Abbrev->extract(abbrData);
    229   return Abbrev.get();
    230 }
    231 
    232 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
    233   if (AbbrevDWO)
    234     return AbbrevDWO.get();
    235 
    236   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
    237   AbbrevDWO.reset(new DWARFDebugAbbrev());
    238   AbbrevDWO->extract(abbrData);
    239   return AbbrevDWO.get();
    240 }
    241 
    242 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
    243   if (Loc)
    244     return Loc.get();
    245 
    246   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
    247   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
    248   // assume all compile units have the same address byte size
    249   if (getNumCompileUnits())
    250     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
    251   return Loc.get();
    252 }
    253 
    254 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
    255   if (LocDWO)
    256     return LocDWO.get();
    257 
    258   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
    259   LocDWO.reset(new DWARFDebugLocDWO());
    260   LocDWO->parse(LocData);
    261   return LocDWO.get();
    262 }
    263 
    264 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
    265   if (Aranges)
    266     return Aranges.get();
    267 
    268   Aranges.reset(new DWARFDebugAranges());
    269   Aranges->generate(this);
    270   return Aranges.get();
    271 }
    272 
    273 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
    274   if (DebugFrame)
    275     return DebugFrame.get();
    276 
    277   // There's a "bug" in the DWARFv3 standard with respect to the target address
    278   // size within debug frame sections. While DWARF is supposed to be independent
    279   // of its container, FDEs have fields with size being "target address size",
    280   // which isn't specified in DWARF in general. It's only specified for CUs, but
    281   // .eh_frame can appear without a .debug_info section. Follow the example of
    282   // other tools (libdwarf) and extract this from the container (ObjectFile
    283   // provides this information). This problem is fixed in DWARFv4
    284   // See this dwarf-discuss discussion for more details:
    285   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
    286   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
    287                                getAddressSize());
    288   DebugFrame.reset(new DWARFDebugFrame());
    289   DebugFrame->parse(debugFrameData);
    290   return DebugFrame.get();
    291 }
    292 
    293 const DWARFLineTable *
    294 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
    295   if (!Line)
    296     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
    297 
    298   unsigned stmtOffset =
    299       cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
    300           cu, DW_AT_stmt_list, -1U);
    301   if (stmtOffset == -1U)
    302     return nullptr; // No line table for this compile unit.
    303 
    304   // See if the line table is cached.
    305   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
    306     return lt;
    307 
    308   // We have to parse it first.
    309   DataExtractor lineData(getLineSection().Data, isLittleEndian(),
    310                          cu->getAddressByteSize());
    311   return Line->getOrParseLineTable(lineData, stmtOffset);
    312 }
    313 
    314 void DWARFContext::parseCompileUnits() {
    315   if (!CUs.empty())
    316     return;
    317   uint32_t offset = 0;
    318   const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
    319                                               isLittleEndian(), 0);
    320   while (DIData.isValidOffset(offset)) {
    321     std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
    322         getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
    323         getStringSection(), StringRef(), getAddrSection(),
    324         &getInfoSection().Relocs, isLittleEndian()));
    325     if (!CU->extract(DIData, &offset)) {
    326       break;
    327     }
    328     CUs.push_back(std::move(CU));
    329     offset = CUs.back()->getNextUnitOffset();
    330   }
    331 }
    332 
    333 void DWARFContext::parseTypeUnits() {
    334   if (!TUs.empty())
    335     return;
    336   for (const auto &I : getTypesSections()) {
    337     uint32_t offset = 0;
    338     const DataExtractor &DIData =
    339         DataExtractor(I.second.Data, isLittleEndian(), 0);
    340     while (DIData.isValidOffset(offset)) {
    341       std::unique_ptr<DWARFTypeUnit> TU(
    342           new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(),
    343                             getStringSection(), StringRef(), getAddrSection(),
    344                             &I.second.Relocs, isLittleEndian()));
    345       if (!TU->extract(DIData, &offset))
    346         break;
    347       TUs.push_back(std::move(TU));
    348       offset = TUs.back()->getNextUnitOffset();
    349     }
    350   }
    351 }
    352 
    353 void DWARFContext::parseDWOCompileUnits() {
    354   if (!DWOCUs.empty())
    355     return;
    356   uint32_t offset = 0;
    357   const DataExtractor &DIData =
    358       DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
    359   while (DIData.isValidOffset(offset)) {
    360     std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
    361         getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
    362         getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
    363         &getInfoDWOSection().Relocs, isLittleEndian()));
    364     if (!DWOCU->extract(DIData, &offset)) {
    365       break;
    366     }
    367     DWOCUs.push_back(std::move(DWOCU));
    368     offset = DWOCUs.back()->getNextUnitOffset();
    369   }
    370 }
    371 
    372 void DWARFContext::parseDWOTypeUnits() {
    373   if (!DWOTUs.empty())
    374     return;
    375   for (const auto &I : getTypesDWOSections()) {
    376     uint32_t offset = 0;
    377     const DataExtractor &DIData =
    378         DataExtractor(I.second.Data, isLittleEndian(), 0);
    379     while (DIData.isValidOffset(offset)) {
    380       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
    381           getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
    382           getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
    383           &I.second.Relocs, isLittleEndian()));
    384       if (!TU->extract(DIData, &offset))
    385         break;
    386       DWOTUs.push_back(std::move(TU));
    387       offset = DWOTUs.back()->getNextUnitOffset();
    388     }
    389   }
    390 }
    391 
    392 namespace {
    393   struct OffsetComparator {
    394 
    395     bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
    396                     const std::unique_ptr<DWARFCompileUnit> &RHS) const {
    397       return LHS->getOffset() < RHS->getOffset();
    398     }
    399     bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
    400                     uint32_t RHS) const {
    401       return LHS->getOffset() < RHS;
    402     }
    403     bool operator()(uint32_t LHS,
    404                     const std::unique_ptr<DWARFCompileUnit> &RHS) const {
    405       return LHS < RHS->getOffset();
    406     }
    407   };
    408 }
    409 
    410 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
    411   parseCompileUnits();
    412 
    413   std::unique_ptr<DWARFCompileUnit> *CU =
    414       std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
    415   if (CU != CUs.end()) {
    416     return CU->get();
    417   }
    418   return nullptr;
    419 }
    420 
    421 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
    422   // First, get the offset of the compile unit.
    423   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
    424   // Retrieve the compile unit.
    425   return getCompileUnitForOffset(CUOffset);
    426 }
    427 
    428 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
    429                                       const DWARFLineTable *LineTable,
    430                                       uint64_t FileIndex, FileLineInfoKind Kind,
    431                                       std::string &FileName) {
    432   if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
    433       !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
    434     return false;
    435   if (Kind == FileLineInfoKind::AbsoluteFilePath &&
    436       sys::path::is_relative(FileName)) {
    437     // We may still need to append compilation directory of compile unit.
    438     SmallString<16> AbsolutePath;
    439     if (const char *CompilationDir = CU->getCompilationDir()) {
    440       sys::path::append(AbsolutePath, CompilationDir);
    441     }
    442     sys::path::append(AbsolutePath, FileName);
    443     FileName = AbsolutePath.str();
    444   }
    445   return true;
    446 }
    447 
    448 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
    449                                           const DWARFLineTable *LineTable,
    450                                           uint64_t Address,
    451                                           FileLineInfoKind Kind,
    452                                           DILineInfo &Result) {
    453   if (!CU || !LineTable)
    454     return false;
    455   // Get the index of row we're looking for in the line table.
    456   uint32_t RowIndex = LineTable->lookupAddress(Address);
    457   if (RowIndex == -1U)
    458     return false;
    459   // Take file number and line/column from the row.
    460   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
    461   if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
    462                                  Result.FileName))
    463     return false;
    464   Result.Line = Row.Line;
    465   Result.Column = Row.Column;
    466   return true;
    467 }
    468 
    469 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
    470                                       FunctionNameKind Kind,
    471                                       std::string &FunctionName) {
    472   if (Kind == FunctionNameKind::None)
    473     return false;
    474   // The address may correspond to instruction in some inlined function,
    475   // so we have to build the chain of inlined functions and take the
    476   // name of the topmost function in it.
    477   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
    478       CU->getInlinedChainForAddress(Address);
    479   if (InlinedChain.DIEs.size() == 0)
    480     return false;
    481   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
    482   if (const char *Name =
    483           TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
    484     FunctionName = Name;
    485     return true;
    486   }
    487   return false;
    488 }
    489 
    490 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
    491                                                DILineInfoSpecifier Spec) {
    492   DILineInfo Result;
    493 
    494   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
    495   if (!CU)
    496     return Result;
    497   getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
    498   if (Spec.FLIKind != FileLineInfoKind::None) {
    499     const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
    500     getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
    501   }
    502   return Result;
    503 }
    504 
    505 DILineInfoTable
    506 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
    507                                          DILineInfoSpecifier Spec) {
    508   DILineInfoTable  Lines;
    509   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
    510   if (!CU)
    511     return Lines;
    512 
    513   std::string FunctionName = "<invalid>";
    514   getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
    515 
    516   // If the Specifier says we don't need FileLineInfo, just
    517   // return the top-most function at the starting address.
    518   if (Spec.FLIKind == FileLineInfoKind::None) {
    519     DILineInfo Result;
    520     Result.FunctionName = FunctionName;
    521     Lines.push_back(std::make_pair(Address, Result));
    522     return Lines;
    523   }
    524 
    525   const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
    526 
    527   // Get the index of row we're looking for in the line table.
    528   std::vector<uint32_t> RowVector;
    529   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
    530     return Lines;
    531 
    532   for (uint32_t RowIndex : RowVector) {
    533     // Take file number and line/column from the row.
    534     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
    535     DILineInfo Result;
    536     getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
    537                               Result.FileName);
    538     Result.FunctionName = FunctionName;
    539     Result.Line = Row.Line;
    540     Result.Column = Row.Column;
    541     Lines.push_back(std::make_pair(Row.Address, Result));
    542   }
    543 
    544   return Lines;
    545 }
    546 
    547 DIInliningInfo
    548 DWARFContext::getInliningInfoForAddress(uint64_t Address,
    549                                         DILineInfoSpecifier Spec) {
    550   DIInliningInfo InliningInfo;
    551 
    552   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
    553   if (!CU)
    554     return InliningInfo;
    555 
    556   const DWARFLineTable *LineTable = nullptr;
    557   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
    558       CU->getInlinedChainForAddress(Address);
    559   if (InlinedChain.DIEs.size() == 0) {
    560     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
    561     // try to at least get file/line info from symbol table.
    562     if (Spec.FLIKind != FileLineInfoKind::None) {
    563       DILineInfo Frame;
    564       LineTable = getLineTableForCompileUnit(CU);
    565       if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
    566                                         Frame)) {
    567         InliningInfo.addFrame(Frame);
    568       }
    569     }
    570     return InliningInfo;
    571   }
    572 
    573   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
    574   for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
    575     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
    576     DILineInfo Frame;
    577     // Get function name if necessary.
    578     if (const char *Name =
    579             FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
    580       Frame.FunctionName = Name;
    581     if (Spec.FLIKind != FileLineInfoKind::None) {
    582       if (i == 0) {
    583         // For the topmost frame, initialize the line table of this
    584         // compile unit and fetch file/line info from it.
    585         LineTable = getLineTableForCompileUnit(CU);
    586         // For the topmost routine, get file/line info from line table.
    587         getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
    588                                       Frame);
    589       } else {
    590         // Otherwise, use call file, call line and call column from
    591         // previous DIE in inlined chain.
    592         getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
    593                                   Frame.FileName);
    594         Frame.Line = CallLine;
    595         Frame.Column = CallColumn;
    596       }
    597       // Get call file/line/column of a current DIE.
    598       if (i + 1 < n) {
    599         FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
    600                                    CallColumn);
    601       }
    602     }
    603     InliningInfo.addFrame(Frame);
    604   }
    605   return InliningInfo;
    606 }
    607 
    608 static bool consumeCompressedDebugSectionHeader(StringRef &data,
    609                                                 uint64_t &OriginalSize) {
    610   // Consume "ZLIB" prefix.
    611   if (!data.startswith("ZLIB"))
    612     return false;
    613   data = data.substr(4);
    614   // Consume uncompressed section size (big-endian 8 bytes).
    615   DataExtractor extractor(data, false, 8);
    616   uint32_t Offset = 0;
    617   OriginalSize = extractor.getU64(&Offset);
    618   if (Offset == 0)
    619     return false;
    620   data = data.substr(Offset);
    621   return true;
    622 }
    623 
    624 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
    625     : IsLittleEndian(Obj->isLittleEndian()),
    626       AddressSize(Obj->getBytesInAddress()) {
    627   for (const SectionRef &Section : Obj->sections()) {
    628     StringRef name;
    629     Section.getName(name);
    630     StringRef data;
    631     Section.getContents(data);
    632 
    633     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
    634 
    635     // Check if debug info section is compressed with zlib.
    636     if (name.startswith("zdebug_")) {
    637       uint64_t OriginalSize;
    638       if (!zlib::isAvailable() ||
    639           !consumeCompressedDebugSectionHeader(data, OriginalSize))
    640         continue;
    641       UncompressedSections.resize(UncompressedSections.size() + 1);
    642       if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
    643           zlib::StatusOK) {
    644         UncompressedSections.pop_back();
    645         continue;
    646       }
    647       // Make data point to uncompressed section contents and save its contents.
    648       name = name.substr(1);
    649       data = UncompressedSections.back();
    650     }
    651 
    652     StringRef *SectionData =
    653         StringSwitch<StringRef *>(name)
    654             .Case("debug_info", &InfoSection.Data)
    655             .Case("debug_abbrev", &AbbrevSection)
    656             .Case("debug_loc", &LocSection.Data)
    657             .Case("debug_line", &LineSection.Data)
    658             .Case("debug_aranges", &ARangeSection)
    659             .Case("debug_frame", &DebugFrameSection)
    660             .Case("debug_str", &StringSection)
    661             .Case("debug_ranges", &RangeSection)
    662             .Case("debug_pubnames", &PubNamesSection)
    663             .Case("debug_pubtypes", &PubTypesSection)
    664             .Case("debug_gnu_pubnames", &GnuPubNamesSection)
    665             .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
    666             .Case("debug_info.dwo", &InfoDWOSection.Data)
    667             .Case("debug_abbrev.dwo", &AbbrevDWOSection)
    668             .Case("debug_loc.dwo", &LocDWOSection.Data)
    669             .Case("debug_line.dwo", &LineDWOSection.Data)
    670             .Case("debug_str.dwo", &StringDWOSection)
    671             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
    672             .Case("debug_addr", &AddrSection)
    673             // Any more debug info sections go here.
    674             .Default(nullptr);
    675     if (SectionData) {
    676       *SectionData = data;
    677       if (name == "debug_ranges") {
    678         // FIXME: Use the other dwo range section when we emit it.
    679         RangeDWOSection = data;
    680       }
    681     } else if (name == "debug_types") {
    682       // Find debug_types data by section rather than name as there are
    683       // multiple, comdat grouped, debug_types sections.
    684       TypesSections[Section].Data = data;
    685     } else if (name == "debug_types.dwo") {
    686       TypesDWOSections[Section].Data = data;
    687     }
    688 
    689     section_iterator RelocatedSection = Section.getRelocatedSection();
    690     if (RelocatedSection == Obj->section_end())
    691       continue;
    692 
    693     StringRef RelSecName;
    694     RelocatedSection->getName(RelSecName);
    695     RelSecName = RelSecName.substr(
    696         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
    697 
    698     // TODO: Add support for relocations in other sections as needed.
    699     // Record relocations for the debug_info and debug_line sections.
    700     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
    701         .Case("debug_info", &InfoSection.Relocs)
    702         .Case("debug_loc", &LocSection.Relocs)
    703         .Case("debug_info.dwo", &InfoDWOSection.Relocs)
    704         .Case("debug_line", &LineSection.Relocs)
    705         .Default(nullptr);
    706     if (!Map) {
    707       // Find debug_types relocs by section rather than name as there are
    708       // multiple, comdat grouped, debug_types sections.
    709       if (RelSecName == "debug_types")
    710         Map = &TypesSections[*RelocatedSection].Relocs;
    711       else if (RelSecName == "debug_types.dwo")
    712         Map = &TypesDWOSections[*RelocatedSection].Relocs;
    713       else
    714         continue;
    715     }
    716 
    717     if (Section.relocation_begin() != Section.relocation_end()) {
    718       uint64_t SectionSize;
    719       RelocatedSection->getSize(SectionSize);
    720       for (const RelocationRef &Reloc : Section.relocations()) {
    721         uint64_t Address;
    722         Reloc.getOffset(Address);
    723         uint64_t Type;
    724         Reloc.getType(Type);
    725         uint64_t SymAddr = 0;
    726         // ELF relocations may need the symbol address
    727         if (Obj->isELF()) {
    728           object::symbol_iterator Sym = Reloc.getSymbol();
    729           Sym->getAddress(SymAddr);
    730         }
    731 
    732         object::RelocVisitor V(Obj->getFileFormatName());
    733         // The section address is always 0 for debug sections.
    734         object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
    735         if (V.error()) {
    736           SmallString<32> Name;
    737           std::error_code ec(Reloc.getTypeName(Name));
    738           if (ec) {
    739             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
    740           }
    741           errs() << "error: failed to compute relocation: "
    742                  << Name << "\n";
    743           continue;
    744         }
    745 
    746         if (Address + R.Width > SectionSize) {
    747           errs() << "error: " << R.Width << "-byte relocation starting "
    748                  << Address << " bytes into section " << name << " which is "
    749                  << SectionSize << " bytes long.\n";
    750           continue;
    751         }
    752         if (R.Width > 8) {
    753           errs() << "error: can't handle a relocation of more than 8 bytes at "
    754                     "a time.\n";
    755           continue;
    756         }
    757         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
    758                      << " at " << format("%p", Address)
    759                      << " with width " << format("%d", R.Width)
    760                      << "\n");
    761         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
    762       }
    763     }
    764   }
    765 }
    766 
    767 void DWARFContextInMemory::anchor() { }
    768