LLVM API Documentation

DWARFContext.cpp
Go to the documentation of this file.
00001 //===-- DWARFContext.cpp --------------------------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "DWARFContext.h"
00011 #include "DWARFDebugArangeSet.h"
00012 
00013 #include "llvm/ADT/SmallString.h"
00014 #include "llvm/ADT/StringSwitch.h"
00015 #include "llvm/Support/Compression.h"
00016 #include "llvm/Support/Dwarf.h"
00017 #include "llvm/Support/Format.h"
00018 #include "llvm/Support/Path.h"
00019 #include "llvm/Support/raw_ostream.h"
00020 #include <algorithm>
00021 using namespace llvm;
00022 using namespace dwarf;
00023 using namespace object;
00024 
00025 #define DEBUG_TYPE "dwarf"
00026 
00027 typedef DWARFDebugLine::LineTable DWARFLineTable;
00028 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
00029 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
00030 
00031 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
00032                            bool LittleEndian, bool GnuStyle) {
00033   OS << "\n." << Name << " contents:\n";
00034   DataExtractor pubNames(Data, LittleEndian, 0);
00035   uint32_t offset = 0;
00036   while (pubNames.isValidOffset(offset)) {
00037     OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
00038     OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
00039     OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
00040     OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
00041     if (GnuStyle)
00042       OS << "Offset     Linkage  Kind     Name\n";
00043     else
00044       OS << "Offset     Name\n";
00045 
00046     while (offset < Data.size()) {
00047       uint32_t dieRef = pubNames.getU32(&offset);
00048       if (dieRef == 0)
00049         break;
00050       OS << format("0x%8.8x ", dieRef);
00051       if (GnuStyle) {
00052         PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
00053         OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
00054            << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
00055            << ' ';
00056       }
00057       OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
00058     }
00059   }
00060 }
00061 
00062 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
00063   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
00064     OS << ".debug_abbrev contents:\n";
00065     getDebugAbbrev()->dump(OS);
00066   }
00067 
00068   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
00069     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
00070       OS << "\n.debug_abbrev.dwo contents:\n";
00071       D->dump(OS);
00072     }
00073 
00074   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
00075     OS << "\n.debug_info contents:\n";
00076     for (const auto &CU : compile_units())
00077       CU->dump(OS);
00078   }
00079 
00080   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
00081       getNumDWOCompileUnits()) {
00082     OS << "\n.debug_info.dwo contents:\n";
00083     for (const auto &DWOCU : dwo_compile_units())
00084       DWOCU->dump(OS);
00085   }
00086 
00087   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
00088     OS << "\n.debug_types contents:\n";
00089     for (const auto &TU : type_units())
00090       TU->dump(OS);
00091   }
00092 
00093   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
00094       getNumDWOTypeUnits()) {
00095     OS << "\n.debug_types.dwo contents:\n";
00096     for (const auto &DWOTU : dwo_type_units())
00097       DWOTU->dump(OS);
00098   }
00099 
00100   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
00101     OS << "\n.debug_loc contents:\n";
00102     getDebugLoc()->dump(OS);
00103   }
00104 
00105   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
00106     OS << "\n.debug_loc.dwo contents:\n";
00107     getDebugLocDWO()->dump(OS);
00108   }
00109 
00110   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
00111     OS << "\n.debug_frame contents:\n";
00112     getDebugFrame()->dump(OS);
00113   }
00114 
00115   uint32_t offset = 0;
00116   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
00117     OS << "\n.debug_aranges contents:\n";
00118     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
00119     DWARFDebugArangeSet set;
00120     while (set.extract(arangesData, &offset))
00121       set.dump(OS);
00122   }
00123 
00124   uint8_t savedAddressByteSize = 0;
00125   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
00126     OS << "\n.debug_line contents:\n";
00127     for (const auto &CU : compile_units()) {
00128       savedAddressByteSize = CU->getAddressByteSize();
00129       unsigned stmtOffset =
00130           CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
00131               CU.get(), DW_AT_stmt_list, -1U);
00132       if (stmtOffset != -1U) {
00133         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
00134                                savedAddressByteSize);
00135         DWARFDebugLine::LineTable LineTable;
00136         LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
00137         LineTable.dump(OS);
00138       }
00139     }
00140   }
00141 
00142   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
00143     OS << "\n.debug_line.dwo contents:\n";
00144     unsigned stmtOffset = 0;
00145     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
00146                            savedAddressByteSize);
00147     DWARFDebugLine::LineTable LineTable;
00148     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
00149       LineTable.dump(OS);
00150       LineTable.clear();
00151     }
00152   }
00153 
00154   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
00155     OS << "\n.debug_str contents:\n";
00156     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
00157     offset = 0;
00158     uint32_t strOffset = 0;
00159     while (const char *s = strData.getCStr(&offset)) {
00160       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
00161       strOffset = offset;
00162     }
00163   }
00164 
00165   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
00166       !getStringDWOSection().empty()) {
00167     OS << "\n.debug_str.dwo contents:\n";
00168     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
00169     offset = 0;
00170     uint32_t strDWOOffset = 0;
00171     while (const char *s = strDWOData.getCStr(&offset)) {
00172       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
00173       strDWOOffset = offset;
00174     }
00175   }
00176 
00177   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
00178     OS << "\n.debug_ranges contents:\n";
00179     // In fact, different compile units may have different address byte
00180     // sizes, but for simplicity we just use the address byte size of the last
00181     // compile unit (there is no easy and fast way to associate address range
00182     // list and the compile unit it describes).
00183     DataExtractor rangesData(getRangeSection(), isLittleEndian(),
00184                              savedAddressByteSize);
00185     offset = 0;
00186     DWARFDebugRangeList rangeList;
00187     while (rangeList.extract(rangesData, &offset))
00188       rangeList.dump(OS);
00189   }
00190 
00191   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
00192     dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
00193                    isLittleEndian(), false);
00194 
00195   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
00196     dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
00197                    isLittleEndian(), false);
00198 
00199   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
00200     dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
00201                    isLittleEndian(), true /* GnuStyle */);
00202 
00203   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
00204     dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
00205                    isLittleEndian(), true /* GnuStyle */);
00206 
00207   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
00208       !getStringOffsetDWOSection().empty()) {
00209     OS << "\n.debug_str_offsets.dwo contents:\n";
00210     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
00211                                0);
00212     offset = 0;
00213     uint64_t size = getStringOffsetDWOSection().size();
00214     while (offset < size) {
00215       OS << format("0x%8.8x: ", offset);
00216       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
00217     }
00218   }
00219 }
00220 
00221 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
00222   if (Abbrev)
00223     return Abbrev.get();
00224 
00225   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
00226 
00227   Abbrev.reset(new DWARFDebugAbbrev());
00228   Abbrev->extract(abbrData);
00229   return Abbrev.get();
00230 }
00231 
00232 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
00233   if (AbbrevDWO)
00234     return AbbrevDWO.get();
00235 
00236   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
00237   AbbrevDWO.reset(new DWARFDebugAbbrev());
00238   AbbrevDWO->extract(abbrData);
00239   return AbbrevDWO.get();
00240 }
00241 
00242 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
00243   if (Loc)
00244     return Loc.get();
00245 
00246   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
00247   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
00248   // assume all compile units have the same address byte size
00249   if (getNumCompileUnits())
00250     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
00251   return Loc.get();
00252 }
00253 
00254 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
00255   if (LocDWO)
00256     return LocDWO.get();
00257 
00258   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
00259   LocDWO.reset(new DWARFDebugLocDWO());
00260   LocDWO->parse(LocData);
00261   return LocDWO.get();
00262 }
00263 
00264 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
00265   if (Aranges)
00266     return Aranges.get();
00267 
00268   Aranges.reset(new DWARFDebugAranges());
00269   Aranges->generate(this);
00270   return Aranges.get();
00271 }
00272 
00273 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
00274   if (DebugFrame)
00275     return DebugFrame.get();
00276 
00277   // There's a "bug" in the DWARFv3 standard with respect to the target address
00278   // size within debug frame sections. While DWARF is supposed to be independent
00279   // of its container, FDEs have fields with size being "target address size",
00280   // which isn't specified in DWARF in general. It's only specified for CUs, but
00281   // .eh_frame can appear without a .debug_info section. Follow the example of
00282   // other tools (libdwarf) and extract this from the container (ObjectFile
00283   // provides this information). This problem is fixed in DWARFv4
00284   // See this dwarf-discuss discussion for more details:
00285   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
00286   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
00287                                getAddressSize());
00288   DebugFrame.reset(new DWARFDebugFrame());
00289   DebugFrame->parse(debugFrameData);
00290   return DebugFrame.get();
00291 }
00292 
00293 const DWARFLineTable *
00294 DWARFContext::getLineTableForUnit(DWARFUnit *cu) {
00295   if (!Line)
00296     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
00297 
00298   unsigned stmtOffset =
00299       cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
00300           cu, DW_AT_stmt_list, -1U);
00301   if (stmtOffset == -1U)
00302     return nullptr; // No line table for this compile unit.
00303 
00304   // See if the line table is cached.
00305   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
00306     return lt;
00307 
00308   // We have to parse it first.
00309   DataExtractor lineData(getLineSection().Data, isLittleEndian(),
00310                          cu->getAddressByteSize());
00311   return Line->getOrParseLineTable(lineData, stmtOffset);
00312 }
00313 
00314 void DWARFContext::parseCompileUnits() {
00315   if (!CUs.empty())
00316     return;
00317   uint32_t offset = 0;
00318   const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
00319                                               isLittleEndian(), 0);
00320   while (DIData.isValidOffset(offset)) {
00321     std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(*this,
00322         getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
00323         getStringSection(), StringRef(), getAddrSection(),
00324         &getInfoSection().Relocs, isLittleEndian(), CUs));
00325     if (!CU->extract(DIData, &offset)) {
00326       break;
00327     }
00328     CUs.push_back(std::move(CU));
00329     offset = CUs.back()->getNextUnitOffset();
00330   }
00331 }
00332 
00333 void DWARFContext::parseTypeUnits() {
00334   if (!TUs.empty())
00335     return;
00336   for (const auto &I : getTypesSections()) {
00337     uint32_t offset = 0;
00338     const DataExtractor &DIData =
00339         DataExtractor(I.second.Data, isLittleEndian(), 0);
00340     while (DIData.isValidOffset(offset)) {
00341       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this,
00342            getDebugAbbrev(), I.second.Data, getRangeSection(),
00343            getStringSection(), StringRef(), getAddrSection(),
00344            &I.second.Relocs, isLittleEndian(), TUs));
00345       if (!TU->extract(DIData, &offset))
00346         break;
00347       TUs.push_back(std::move(TU));
00348       offset = TUs.back()->getNextUnitOffset();
00349     }
00350   }
00351 }
00352 
00353 void DWARFContext::parseDWOCompileUnits() {
00354   if (!DWOCUs.empty())
00355     return;
00356   uint32_t offset = 0;
00357   const DataExtractor &DIData =
00358       DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
00359   while (DIData.isValidOffset(offset)) {
00360     std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(*this,
00361         getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
00362         getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
00363         &getInfoDWOSection().Relocs, isLittleEndian(), DWOCUs));
00364     if (!DWOCU->extract(DIData, &offset)) {
00365       break;
00366     }
00367     DWOCUs.push_back(std::move(DWOCU));
00368     offset = DWOCUs.back()->getNextUnitOffset();
00369   }
00370 }
00371 
00372 void DWARFContext::parseDWOTypeUnits() {
00373   if (!DWOTUs.empty())
00374     return;
00375   for (const auto &I : getTypesDWOSections()) {
00376     uint32_t offset = 0;
00377     const DataExtractor &DIData =
00378         DataExtractor(I.second.Data, isLittleEndian(), 0);
00379     while (DIData.isValidOffset(offset)) {
00380       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this,
00381           getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
00382           getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
00383           &I.second.Relocs, isLittleEndian(), DWOTUs));
00384       if (!TU->extract(DIData, &offset))
00385         break;
00386       DWOTUs.push_back(std::move(TU));
00387       offset = DWOTUs.back()->getNextUnitOffset();
00388     }
00389   }
00390 }
00391 
00392 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
00393   parseCompileUnits();
00394   return CUs.getUnitForOffset(Offset);
00395 }
00396 
00397 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
00398   // First, get the offset of the compile unit.
00399   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
00400   // Retrieve the compile unit.
00401   return getCompileUnitForOffset(CUOffset);
00402 }
00403 
00404 static bool getFileNameForUnit(DWARFCompileUnit *U,
00405                                const DWARFLineTable *LineTable,
00406                                uint64_t FileIndex, FileLineInfoKind Kind,
00407                                std::string &FileName) {
00408   if (!U || !LineTable || Kind == FileLineInfoKind::None ||
00409       !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
00410     return false;
00411   if (Kind == FileLineInfoKind::AbsoluteFilePath &&
00412       sys::path::is_relative(FileName)) {
00413     // We may still need to append compilation directory of compile unit.
00414     SmallString<16> AbsolutePath;
00415     if (const char *CompilationDir = U->getCompilationDir()) {
00416       sys::path::append(AbsolutePath, CompilationDir);
00417     }
00418     sys::path::append(AbsolutePath, FileName);
00419     FileName = AbsolutePath.str();
00420   }
00421   return true;
00422 }
00423 
00424 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
00425                                           const DWARFLineTable *LineTable,
00426                                           uint64_t Address,
00427                                           FileLineInfoKind Kind,
00428                                           DILineInfo &Result) {
00429   if (!CU || !LineTable)
00430     return false;
00431   // Get the index of row we're looking for in the line table.
00432   uint32_t RowIndex = LineTable->lookupAddress(Address);
00433   if (RowIndex == -1U)
00434     return false;
00435   // Take file number and line/column from the row.
00436   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
00437   if (!getFileNameForUnit(CU, LineTable, Row.File, Kind,
00438                           Result.FileName))
00439     return false;
00440   Result.Line = Row.Line;
00441   Result.Column = Row.Column;
00442   return true;
00443 }
00444 
00445 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
00446                                       FunctionNameKind Kind,
00447                                       std::string &FunctionName) {
00448   if (Kind == FunctionNameKind::None)
00449     return false;
00450   // The address may correspond to instruction in some inlined function,
00451   // so we have to build the chain of inlined functions and take the
00452   // name of the topmost function in it.
00453   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
00454       CU->getInlinedChainForAddress(Address);
00455   if (InlinedChain.DIEs.size() == 0)
00456     return false;
00457   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
00458   if (const char *Name =
00459           TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
00460     FunctionName = Name;
00461     return true;
00462   }
00463   return false;
00464 }
00465 
00466 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
00467                                                DILineInfoSpecifier Spec) {
00468   DILineInfo Result;
00469 
00470   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
00471   if (!CU)
00472     return Result;
00473   getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
00474   if (Spec.FLIKind != FileLineInfoKind::None) {
00475     const DWARFLineTable *LineTable = getLineTableForUnit(CU);
00476     getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
00477   }
00478   return Result;
00479 }
00480 
00481 DILineInfoTable
00482 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
00483                                          DILineInfoSpecifier Spec) {
00484   DILineInfoTable  Lines;
00485   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
00486   if (!CU)
00487     return Lines;
00488 
00489   std::string FunctionName = "<invalid>";
00490   getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
00491 
00492   // If the Specifier says we don't need FileLineInfo, just
00493   // return the top-most function at the starting address.
00494   if (Spec.FLIKind == FileLineInfoKind::None) {
00495     DILineInfo Result;
00496     Result.FunctionName = FunctionName;
00497     Lines.push_back(std::make_pair(Address, Result));
00498     return Lines;
00499   }
00500 
00501   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
00502 
00503   // Get the index of row we're looking for in the line table.
00504   std::vector<uint32_t> RowVector;
00505   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
00506     return Lines;
00507 
00508   for (uint32_t RowIndex : RowVector) {
00509     // Take file number and line/column from the row.
00510     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
00511     DILineInfo Result;
00512     getFileNameForUnit(CU, LineTable, Row.File, Spec.FLIKind,
00513                        Result.FileName);
00514     Result.FunctionName = FunctionName;
00515     Result.Line = Row.Line;
00516     Result.Column = Row.Column;
00517     Lines.push_back(std::make_pair(Row.Address, Result));
00518   }
00519 
00520   return Lines;
00521 }
00522 
00523 DIInliningInfo
00524 DWARFContext::getInliningInfoForAddress(uint64_t Address,
00525                                         DILineInfoSpecifier Spec) {
00526   DIInliningInfo InliningInfo;
00527 
00528   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
00529   if (!CU)
00530     return InliningInfo;
00531 
00532   const DWARFLineTable *LineTable = nullptr;
00533   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
00534       CU->getInlinedChainForAddress(Address);
00535   if (InlinedChain.DIEs.size() == 0) {
00536     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
00537     // try to at least get file/line info from symbol table.
00538     if (Spec.FLIKind != FileLineInfoKind::None) {
00539       DILineInfo Frame;
00540       LineTable = getLineTableForUnit(CU);
00541       if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
00542                                         Frame)) {
00543         InliningInfo.addFrame(Frame);
00544       }
00545     }
00546     return InliningInfo;
00547   }
00548 
00549   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
00550   for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
00551     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
00552     DILineInfo Frame;
00553     // Get function name if necessary.
00554     if (const char *Name =
00555             FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
00556       Frame.FunctionName = Name;
00557     if (Spec.FLIKind != FileLineInfoKind::None) {
00558       if (i == 0) {
00559         // For the topmost frame, initialize the line table of this
00560         // compile unit and fetch file/line info from it.
00561         LineTable = getLineTableForUnit(CU);
00562         // For the topmost routine, get file/line info from line table.
00563         getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
00564                                       Frame);
00565       } else {
00566         // Otherwise, use call file, call line and call column from
00567         // previous DIE in inlined chain.
00568         getFileNameForUnit(CU, LineTable, CallFile, Spec.FLIKind,
00569                            Frame.FileName);
00570         Frame.Line = CallLine;
00571         Frame.Column = CallColumn;
00572       }
00573       // Get call file/line/column of a current DIE.
00574       if (i + 1 < n) {
00575         FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
00576                                    CallColumn);
00577       }
00578     }
00579     InliningInfo.addFrame(Frame);
00580   }
00581   return InliningInfo;
00582 }
00583 
00584 static bool consumeCompressedDebugSectionHeader(StringRef &data,
00585                                                 uint64_t &OriginalSize) {
00586   // Consume "ZLIB" prefix.
00587   if (!data.startswith("ZLIB"))
00588     return false;
00589   data = data.substr(4);
00590   // Consume uncompressed section size (big-endian 8 bytes).
00591   DataExtractor extractor(data, false, 8);
00592   uint32_t Offset = 0;
00593   OriginalSize = extractor.getU64(&Offset);
00594   if (Offset == 0)
00595     return false;
00596   data = data.substr(Offset);
00597   return true;
00598 }
00599 
00600 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
00601     : IsLittleEndian(Obj.isLittleEndian()),
00602       AddressSize(Obj.getBytesInAddress()) {
00603   for (const SectionRef &Section : Obj.sections()) {
00604     StringRef name;
00605     Section.getName(name);
00606     StringRef data;
00607     Section.getContents(data);
00608 
00609     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
00610 
00611     // Check if debug info section is compressed with zlib.
00612     if (name.startswith("zdebug_")) {
00613       uint64_t OriginalSize;
00614       if (!zlib::isAvailable() ||
00615           !consumeCompressedDebugSectionHeader(data, OriginalSize))
00616         continue;
00617       UncompressedSections.resize(UncompressedSections.size() + 1);
00618       if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
00619           zlib::StatusOK) {
00620         UncompressedSections.pop_back();
00621         continue;
00622       }
00623       // Make data point to uncompressed section contents and save its contents.
00624       name = name.substr(1);
00625       data = UncompressedSections.back();
00626     }
00627 
00628     StringRef *SectionData =
00629         StringSwitch<StringRef *>(name)
00630             .Case("debug_info", &InfoSection.Data)
00631             .Case("debug_abbrev", &AbbrevSection)
00632             .Case("debug_loc", &LocSection.Data)
00633             .Case("debug_line", &LineSection.Data)
00634             .Case("debug_aranges", &ARangeSection)
00635             .Case("debug_frame", &DebugFrameSection)
00636             .Case("debug_str", &StringSection)
00637             .Case("debug_ranges", &RangeSection)
00638             .Case("debug_pubnames", &PubNamesSection)
00639             .Case("debug_pubtypes", &PubTypesSection)
00640             .Case("debug_gnu_pubnames", &GnuPubNamesSection)
00641             .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
00642             .Case("debug_info.dwo", &InfoDWOSection.Data)
00643             .Case("debug_abbrev.dwo", &AbbrevDWOSection)
00644             .Case("debug_loc.dwo", &LocDWOSection.Data)
00645             .Case("debug_line.dwo", &LineDWOSection.Data)
00646             .Case("debug_str.dwo", &StringDWOSection)
00647             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
00648             .Case("debug_addr", &AddrSection)
00649             // Any more debug info sections go here.
00650             .Default(nullptr);
00651     if (SectionData) {
00652       *SectionData = data;
00653       if (name == "debug_ranges") {
00654         // FIXME: Use the other dwo range section when we emit it.
00655         RangeDWOSection = data;
00656       }
00657     } else if (name == "debug_types") {
00658       // Find debug_types data by section rather than name as there are
00659       // multiple, comdat grouped, debug_types sections.
00660       TypesSections[Section].Data = data;
00661     } else if (name == "debug_types.dwo") {
00662       TypesDWOSections[Section].Data = data;
00663     }
00664 
00665     section_iterator RelocatedSection = Section.getRelocatedSection();
00666     if (RelocatedSection == Obj.section_end())
00667       continue;
00668 
00669     StringRef RelSecName;
00670     RelocatedSection->getName(RelSecName);
00671     RelSecName = RelSecName.substr(
00672         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
00673 
00674     // TODO: Add support for relocations in other sections as needed.
00675     // Record relocations for the debug_info and debug_line sections.
00676     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
00677         .Case("debug_info", &InfoSection.Relocs)
00678         .Case("debug_loc", &LocSection.Relocs)
00679         .Case("debug_info.dwo", &InfoDWOSection.Relocs)
00680         .Case("debug_line", &LineSection.Relocs)
00681         .Default(nullptr);
00682     if (!Map) {
00683       // Find debug_types relocs by section rather than name as there are
00684       // multiple, comdat grouped, debug_types sections.
00685       if (RelSecName == "debug_types")
00686         Map = &TypesSections[*RelocatedSection].Relocs;
00687       else if (RelSecName == "debug_types.dwo")
00688         Map = &TypesDWOSections[*RelocatedSection].Relocs;
00689       else
00690         continue;
00691     }
00692 
00693     if (Section.relocation_begin() != Section.relocation_end()) {
00694       uint64_t SectionSize;
00695       RelocatedSection->getSize(SectionSize);
00696       for (const RelocationRef &Reloc : Section.relocations()) {
00697         uint64_t Address;
00698         Reloc.getOffset(Address);
00699         uint64_t Type;
00700         Reloc.getType(Type);
00701         uint64_t SymAddr = 0;
00702         // ELF relocations may need the symbol address
00703         if (Obj.isELF()) {
00704           object::symbol_iterator Sym = Reloc.getSymbol();
00705           Sym->getAddress(SymAddr);
00706         }
00707 
00708         object::RelocVisitor V(Obj.getFileFormatName());
00709         // The section address is always 0 for debug sections.
00710         object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
00711         if (V.error()) {
00712           SmallString<32> Name;
00713           std::error_code ec(Reloc.getTypeName(Name));
00714           if (ec) {
00715             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
00716           }
00717           errs() << "error: failed to compute relocation: "
00718                  << Name << "\n";
00719           continue;
00720         }
00721 
00722         if (Address + R.Width > SectionSize) {
00723           errs() << "error: " << R.Width << "-byte relocation starting "
00724                  << Address << " bytes into section " << name << " which is "
00725                  << SectionSize << " bytes long.\n";
00726           continue;
00727         }
00728         if (R.Width > 8) {
00729           errs() << "error: can't handle a relocation of more than 8 bytes at "
00730                     "a time.\n";
00731           continue;
00732         }
00733         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
00734                      << " at " << format("%p", Address)
00735                      << " with width " << format("%d", R.Width)
00736                      << "\n");
00737         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
00738       }
00739     }
00740   }
00741 }
00742 
00743 void DWARFContextInMemory::anchor() { }