X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFContext.cpp;h=fc8d93dce3d0c8a5fde50f532e1f85e3be53da8c;hb=184c0f8b2f6dfcca8137b019190fef52a3ff10e2;hp=5b65d0ae1a6589ae68d52dcf87ce3eda4293be7b;hpb=0b6cb7104b15504cd41f48cc2babcbcee70775f3;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 5b65d0ae1a6..fc8d93dce3d 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" @@ -20,7 +22,11 @@ using namespace llvm; using namespace dwarf; 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) { @@ -126,8 +132,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); } } } @@ -137,9 +144,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) { @@ -216,7 +225,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); Abbrev.reset(new DWARFDebugAbbrev()); - Abbrev->parse(abbrData); + Abbrev->extract(abbrData); return Abbrev.get(); } @@ -226,7 +235,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() { DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0); AbbrevDWO.reset(new DWARFDebugAbbrev()); - AbbrevDWO->parse(abbrData); + AbbrevDWO->extract(abbrData); return AbbrevDWO.get(); } @@ -310,8 +319,8 @@ void DWARFContext::parseCompileUnits() { isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { std::unique_ptr CU(new DWARFCompileUnit( - getDebugAbbrev(), getInfoSection().Data, getAbbrevSection(), - getRangeSection(), getStringSection(), StringRef(), getAddrSection(), + getDebugAbbrev(), getInfoSection().Data, getRangeSection(), + getStringSection(), StringRef(), getAddrSection(), &getInfoSection().Relocs, isLittleEndian())); if (!CU->extract(DIData, &offset)) { break; @@ -329,10 +338,10 @@ void DWARFContext::parseTypeUnits() { const DataExtractor &DIData = DataExtractor(I.second.Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { - std::unique_ptr TU(new DWARFTypeUnit( - getDebugAbbrev(), I.second.Data, getAbbrevSection(), - getRangeSection(), getStringSection(), StringRef(), getAddrSection(), - &I.second.Relocs, isLittleEndian())); + 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)); @@ -349,9 +358,8 @@ void DWARFContext::parseDWOCompileUnits() { DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { std::unique_ptr DWOCU(new DWARFCompileUnit( - getDebugAbbrevDWO(), getInfoDWOSection().Data, getAbbrevDWOSection(), - getRangeDWOSection(), getStringDWOSection(), - getStringOffsetDWOSection(), getAddrSection(), + getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(), + getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), &getInfoDWOSection().Relocs, isLittleEndian())); if (!DWOCU->extract(DIData, &offset)) { break; @@ -370,10 +378,9 @@ void DWARFContext::parseDWOTypeUnits() { DataExtractor(I.second.Data, isLittleEndian(), 0); while (DIData.isValidOffset(offset)) { std::unique_ptr TU(new DWARFTypeUnit( - getDebugAbbrevDWO(), I.second.Data, getAbbrevDWOSection(), - getRangeDWOSection(), getStringDWOSection(), - getStringOffsetDWOSection(), getAddrSection(), &I.second.Relocs, - isLittleEndian())); + getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(), + getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), + &I.second.Relocs, isLittleEndian())); if (!TU->extract(DIData, &offset)) break; DWOTUs.push_back(std::move(TU)); @@ -420,14 +427,13 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, - uint64_t FileIndex, - bool NeedsAbsoluteFilePath, + uint64_t FileIndex, FileLineInfoKind Kind, std::string &FileName) { - if (!CU || !LineTable || - !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath, - FileName)) + if (!CU || !LineTable || Kind == FileLineInfoKind::None || + !LineTable->getFileNameByIndex(FileIndex, Kind, FileName)) return false; - if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) { + if (Kind == FileLineInfoKind::AbsoluteFilePath && + 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()) { @@ -442,9 +448,8 @@ static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, uint64_t Address, - bool NeedsAbsoluteFilePath, - std::string &FileName, - uint32_t &Line, uint32_t &Column) { + FileLineInfoKind Kind, + DILineInfo &Result) { if (!CU || !LineTable) return false; // Get the index of row we're looking for in the line table. @@ -453,80 +458,71 @@ static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, 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, FileName)) + if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind, + Result.FileName)) return false; - Line = Row.Line; - Column = Row.Column; + 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. + const DWARFDebugInfoEntryInlinedChain &InlinedChain = + CU->getInlinedChainForAddress(Address); + if (InlinedChain.DIEs.size() == 0) + return false; + const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; + if (const char *Name = + TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) { + FunctionName = Name; + return true; + } + return false; +} + DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { + DILineInfoSpecifier Spec) { + DILineInfo Result; + DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) - return DILineInfo(); - std::string FileName = ""; - std::string FunctionName = ""; - uint32_t Line = 0; - uint32_t Column = 0; - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - // 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. - const DWARFDebugInfoEntryInlinedChain &InlinedChain = - CU->getInlinedChainForAddress(Address); - if (InlinedChain.DIEs.size() > 0) { - const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; - } - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { + return Result; + getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName); + if (Spec.FLIKind != FileLineInfoKind::None) { const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU); - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); - getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, - FileName, Line, Column); + getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result); } - return DILineInfo(StringRef(FileName), StringRef(FunctionName), - Line, Column); + 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)) { - // 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. - const DWARFDebugInfoEntryInlinedChain &InlinedChain = - CU->getInlinedChainForAddress(Address); - if (InlinedChain.DIEs.size() > 0) { - const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0]; - if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; - } - } + 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)) { - Lines.push_back( - std::make_pair(Address, DILineInfo("", FunctionName, 0, 0))); + 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); // Get the index of row we're looking for in the line table. std::vector RowVector; @@ -536,59 +532,67 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address, for (uint32_t RowIndex : RowVector) { // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; - std::string FileName = ""; - getFileNameForCompileUnit(CU, LineTable, Row.File, - NeedsAbsoluteFilePath, FileName); - Lines.push_back(std::make_pair( - Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column))); + DILineInfo Result; + getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind, + Result.FileName); + Result.FunctionName = FunctionName; + Result.Line = Row.Line; + Result.Column = Row.Column; + Lines.push_back(std::make_pair(Row.Address, Result)); } return Lines; } -DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, - DILineInfoSpecifier Specifier) { +DIInliningInfo +DWARFContext::getInliningInfoForAddress(uint64_t Address, + DILineInfoSpecifier Spec) { + DIInliningInfo InliningInfo; + DWARFCompileUnit *CU = getCompileUnitForAddress(Address); if (!CU) - return DIInliningInfo(); + return InliningInfo; + const DWARFLineTable *LineTable = nullptr; const DWARFDebugInfoEntryInlinedChain &InlinedChain = CU->getInlinedChainForAddress(Address); - if (InlinedChain.DIEs.size() == 0) - return DIInliningInfo(); + 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 (Spec.FLIKind != FileLineInfoKind::None) { + DILineInfo Frame; + LineTable = getLineTableForCompileUnit(CU); + if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, + Frame)) { + InliningInfo.addFrame(Frame); + } + } + return InliningInfo; + } - DIInliningInfo InliningInfo; uint32_t CallFile = 0, CallLine = 0, CallColumn = 0; - const DWARFLineTable *LineTable = nullptr; for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) { const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i]; - std::string FileName = ""; - std::string FunctionName = ""; - uint32_t Line = 0; - uint32_t Column = 0; + DILineInfo Frame; // Get function name if necessary. - if (Specifier.needs(DILineInfoSpecifier::FunctionName)) { - if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U)) - FunctionName = Name; - } - if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) { - const bool NeedsAbsoluteFilePath = - Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath); + 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); // For the topmost routine, get file/line info from line table. - getFileLineInfoForCompileUnit(CU, LineTable, Address, - NeedsAbsoluteFilePath, - FileName, Line, Column); + getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, + Frame); } else { // Otherwise, use call file, call line and call column from // previous DIE in inlined chain. - getFileNameForCompileUnit(CU, LineTable, CallFile, - NeedsAbsoluteFilePath, FileName); - Line = CallLine; - Column = CallColumn; + getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind, + Frame.FileName); + Frame.Line = CallLine; + Frame.Column = CallColumn; } // Get call file/line/column of a current DIE. if (i + 1 < n) { @@ -596,8 +600,6 @@ DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address, CallColumn); } } - DILineInfo Frame(StringRef(FileName), StringRef(FunctionName), - Line, Column); InliningInfo.addFrame(Frame); } return InliningInfo; @@ -619,10 +621,10 @@ 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); StringRef data; @@ -685,7 +687,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) } section_iterator RelocatedSection = Section.getRelocatedSection(); - if (RelocatedSection == Obj->section_end()) + if (RelocatedSection == Obj.section_end()) continue; StringRef RelSecName; @@ -722,17 +724,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.getFileFormatName()); // 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"; }