X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFContext.cpp;h=2cacfd9b949a0cdaae48d964e1c8345fa10b254e;hb=8d74900819bc1b1e01fdc44d711c381bfbbe7899;hp=76d6106ba5a3547d3cd1905176ffc427ccf387e0;hpb=a189d1ad57e712ff20167269b9014241ed2d84be;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 76d6106ba5a..2cacfd9b949 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "DWARFContext.h" +#include "DWARFDebugArangeSet.h" + #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Compression.h" @@ -23,6 +25,8 @@ using namespace object; #define DEBUG_TYPE "dwarf" typedef DWARFDebugLine::LineTable DWARFLineTable; +typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; +typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, bool LittleEndian, bool GnuStyle) { @@ -82,15 +86,17 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) { OS << "\n.debug_types contents:\n"; - for (const auto &TU : type_units()) - TU->dump(OS); + for (const auto &TUS : type_unit_sections()) + for (const auto &TU : TUS) + TU->dump(OS); } if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) && getNumDWOTypeUnits()) { OS << "\n.debug_types.dwo contents:\n"; - for (const auto &DWOTU : dwo_type_units()) - DWOTU->dump(OS); + for (const auto &DWOTUS : dwo_type_unit_sections()) + for (const auto &DWOTU : DWOTUS) + DWOTU->dump(OS); } if (DumpType == DIDT_All || DumpType == DIDT_Loc) { @@ -128,8 +134,9 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { if (stmtOffset != -1U) { DataExtractor lineData(getLineSection().Data, isLittleEndian(), savedAddressByteSize); - DWARFDebugLine::DumpingState state(OS); - DWARFDebugLine::parseStatementTable(lineData, &getLineSection().Relocs, &stmtOffset, state); + DWARFDebugLine::LineTable LineTable; + LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset); + LineTable.dump(OS); } } } @@ -139,9 +146,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { unsigned stmtOffset = 0; DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(), savedAddressByteSize); - DWARFDebugLine::DumpingState state(OS); - while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue)) - state.finalize(); + DWARFDebugLine::LineTable LineTable; + while (LineTable.Prologue.parse(lineData, &stmtOffset)) { + LineTable.dump(OS); + LineTable.clear(); + } } if (DumpType == DIDT_All || DumpType == DIDT_Str) { @@ -218,7 +227,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); Abbrev.reset(new DWARFDebugAbbrev()); - Abbrev->parse(abbrData); + Abbrev->extract(abbrData); return Abbrev.get(); } @@ -228,7 +237,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0); AbbrevDWO.reset(new DWARFDebugAbbrev()); - AbbrevDWO->parse(abbrData); + AbbrevDWO->extract(abbrData); return AbbrevDWO.get(); } @@ -284,7 +293,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { } const DWARFLineTable * -DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { +DWARFContext::getLineTableForUnit(DWARFUnit *cu) { if (!Line) Line.reset(new DWARFDebugLine(&getLineSection().Relocs)); @@ -305,110 +314,34 @@ DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { } void DWARFContext::parseCompileUnits() { - if (!CUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = DataExtractor(getInfoSection().Data, - isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr CU(new DWARFCompileUnit( - getDebugAbbrev(), getInfoSection().Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &getInfoSection().Relocs, isLittleEndian())); - if (!CU->extract(DIData, &offset)) { - break; - } - CUs.push_back(std::move(CU)); - offset = CUs.back()->getNextUnitOffset(); - } + CUs.parse(*this, getInfoSection()); } void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; for (const auto &I : getTypesSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr TU( - new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &I.second.Relocs, isLittleEndian())); - if (!TU->extract(DIData, &offset)) - break; - TUs.push_back(std::move(TU)); - offset = TUs.back()->getNextUnitOffset(); - } + TUs.push_back(DWARFUnitSection()); + TUs.back().parse(*this, I.second); } } void DWARFContext::parseDWOCompileUnits() { - if (!DWOCUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr DWOCU(new DWARFCompileUnit( - getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &getInfoDWOSection().Relocs, isLittleEndian())); - if (!DWOCU->extract(DIData, &offset)) { - break; - } - DWOCUs.push_back(std::move(DWOCU)); - offset = DWOCUs.back()->getNextUnitOffset(); - } + DWOCUs.parseDWO(*this, getInfoDWOSection()); } void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; for (const auto &I : getTypesDWOSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr TU(new DWARFTypeUnit( - getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &I.second.Relocs, isLittleEndian())); - if (!TU->extract(DIData, &offset)) - break; - DWOTUs.push_back(std::move(TU)); - offset = DWOTUs.back()->getNextUnitOffset(); - } + DWOTUs.push_back(DWARFUnitSection()); + DWOTUs.back().parseDWO(*this, I.second); } } -namespace { - struct OffsetComparator { - - bool operator()(const std::unique_ptr &LHS, - const std::unique_ptr &RHS) const { - return LHS->getOffset() < RHS->getOffset(); - } - bool operator()(const std::unique_ptr &LHS, - uint32_t RHS) const { - return LHS->getOffset() < RHS; - } - bool operator()(uint32_t LHS, - const std::unique_ptr &RHS) const { - return LHS < RHS->getOffset(); - } - }; -} - DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { parseCompileUnits(); - - std::unique_ptr *CU = - std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator()); - if (CU != CUs.end()) { - return CU->get(); - } - return nullptr; + return CUs.getUnitForOffset(Offset); } DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { @@ -418,50 +351,11 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { return getCompileUnitForOffset(CUOffset); } -static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, - const DWARFLineTable *LineTable, - uint64_t FileIndex, - bool NeedsAbsoluteFilePath, - std::string &FileName) { - if (!CU || !LineTable || - !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath, - FileName)) - return false; - if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) { - // We may still need to append compilation directory of compile unit. - SmallString<16> AbsolutePath; - if (const char *CompilationDir = CU->getCompilationDir()) { - sys::path::append(AbsolutePath, CompilationDir); - } - sys::path::append(AbsolutePath, FileName); - FileName = AbsolutePath.str(); - } - return true; -} - -static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, - const DWARFLineTable *LineTable, - uint64_t Address, - bool NeedsAbsoluteFilePath, - DILineInfo &Result) { - if (!CU || !LineTable) - return false; - // Get the index of row we're looking for in the line table. - uint32_t RowIndex = LineTable->lookupAddress(Address); - if (RowIndex == -1U) - return false; - // Take file number and line/column from the row. - const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; - if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath, - Result.FileName)) - return false; - Result.Line = Row.Line; - Result.Column = Row.Column; - return true; -} - static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, + FunctionNameKind Kind, std::string &FunctionName) { + if (Kind == FunctionNameKind::None) + return false; // The address may correspond to instruction in some inlined function, // so we have to build the chain of inlined functions and take the // name of the topmost function in it. @@ -470,7 +364,8 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, if (InlinedChain.DIEs.size() == 0) return false; const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) { + if (const char *Name = + TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) { FunctionName = Name; return true; } @@ -478,50 +373,42 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, } DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { + DILineInfoSpecifier Spec) { DILineInfo Result; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) return Result; - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - getFunctionNameForAddress(CU, Address, Result.FunctionName); - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { - const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); - getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath, - Result); + getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName); + if (Spec.FLIKind != FileLineInfoKind::None) { + if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) + LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + Spec.FLIKind, Result); } return Result; } -DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, - uint64_t Size, - DILineInfoSpecifier Specifier) { +DILineInfoTable +DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, + DILineInfoSpecifier Spec) { DILineInfoTable Lines; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) return Lines; std::string FunctionName = ""; - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - getFunctionNameForAddress(CU, Address, FunctionName); - } + getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName); // If the Specifier says we don't need FileLineInfo, just // return the top-most function at the starting address. - if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + if (Spec.FLIKind == FileLineInfoKind::None) { DILineInfo Result; Result.FunctionName = FunctionName; Lines.push_back(std::make_pair(Address, Result)); return Lines; } - const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); + const DWARFLineTable *LineTable = getLineTableForUnit(CU); // Get the index of row we're looking for in the line table. std::vector RowVector; @@ -532,8 +419,8 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; DILineInfo Result; - getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath, - Result.FileName); + LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(), + Spec.FLIKind, Result.FileName); Result.FunctionName = FunctionName; Result.Line = Row.Line; Result.Column = Row.Column; @@ -543,8 +430,9 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, return Lines; } -DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { +DIInliningInfo +DWARFContext::getInliningInfoForAddress(uint64_t Address, + DILineInfoSpecifier Spec) { DIInliningInfo InliningInfo; DWARFCompileUnit *CU = getCompileUnitForAddress(Address); @@ -552,20 +440,18 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; const DWARFLineTable *LineTable = nullptr; - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); const DWARFDebugInfoEntryInlinedChain &InlinedChain = CU->getInlinedChainForAddress(Address); if (InlinedChain.DIEs.size() == 0) { // If there is no DIE for address (e.g. it is in unavailable .dwo file), // try to at least get file/line info from symbol table. - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + if (Spec.FLIKind != FileLineInfoKind::None) { DILineInfo Frame; - LineTable = getLineTableForCompileUnit(CU); - if (getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, Frame)) { + LineTable = getLineTableForUnit(CU); + if (LineTable && + LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + Spec.FLIKind, Frame)) InliningInfo.addFrame(Frame); - } } return InliningInfo; } @@ -575,23 +461,24 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; DILineInfo Frame; // Get function name if necessary. - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) - Frame.FunctionName = Name; - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + if (const char *Name = + FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind)) + Frame.FunctionName = Name; + if (Spec.FLIKind != FileLineInfoKind::None) { if (i == 0) { // For the topmost frame, initialize the line table of this // compile unit and fetch file/line info from it. - LineTable = getLineTableForCompileUnit(CU); + LineTable = getLineTableForUnit(CU); // For the topmost routine, get file/line info from line table. - getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, Frame); + if (LineTable) + LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + Spec.FLIKind, Frame); } else { // Otherwise, use call file, call line and call column from // previous DIE in inlined chain. - getFileNameForCompileUnit(CU, LineTable, CallFile, - NeedsAbsoluteFilePath, Frame.FileName); + if (LineTable) + LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(), + Spec.FLIKind, Frame.FileName); Frame.Line = CallLine; Frame.Column = CallColumn; } @@ -622,12 +509,21 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data, return true; } -DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) - : IsLittleEndian(Obj->isLittleEndian()), - AddressSize(Obj->getBytesInAddress()) { - for (const SectionRef &Section : Obj->sections()) { +DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj) + : IsLittleEndian(Obj.isLittleEndian()), + AddressSize(Obj.getBytesInAddress()) { + for (const SectionRef &Section : Obj.sections()) { StringRef name; Section.getName(name); + // Skip BSS and Virtual sections, they aren't interesting. + bool IsBSS; + Section.isBSS(IsBSS); + if (IsBSS) + continue; + bool IsVirtual; + Section.isVirtual(IsVirtual); + if (IsVirtual) + continue; StringRef data; Section.getContents(data); @@ -688,7 +584,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) } section_iterator RelocatedSection = Section.getRelocatedSection(); - if (RelocatedSection == Obj->section_end()) + if (RelocatedSection == Obj.section_end()) continue; StringRef RelSecName; @@ -725,17 +621,17 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) Reloc.getType(Type); uint64_t SymAddr = 0; // ELF relocations may need the symbol address - if (Obj->isELF()) { + if (Obj.isELF()) { object::symbol_iterator Sym = Reloc.getSymbol(); Sym->getAddress(SymAddr); } - object::RelocVisitor V(Obj->getFileFormatName()); + object::RelocVisitor V(Obj); // The section address is always 0 for debug sections. object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr)); if (V.error()) { SmallString<32> Name; - error_code ec(Reloc.getTypeName(Name)); + std::error_code ec(Reloc.getTypeName(Name)); if (ec) { errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; }