Index: lib/DebugInfo/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARFContext.cpp +++ lib/DebugInfo/DWARFContext.cpp @@ -401,47 +401,6 @@ return getCompileUnitForOffset(CUOffset); } -static bool getFileNameForUnit(DWARFCompileUnit *U, - const DWARFLineTable *LineTable, - uint64_t FileIndex, FileLineInfoKind Kind, - std::string &FileName) { - if (!U || !LineTable || Kind == FileLineInfoKind::None || - !LineTable->getFileNameByIndex(FileIndex, Kind, FileName)) - return false; - 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 = U->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, - FileLineInfoKind Kind, - 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 (!getFileNameForUnit(CU, LineTable, Row.File, Kind, - 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) { @@ -472,8 +431,9 @@ return Result; getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName); if (Spec.FLIKind != FileLineInfoKind::None) { - const DWARFLineTable *LineTable = getLineTableForUnit(CU); - getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result); + if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) + LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + Spec.FLIKind, Result); } return Result; } @@ -509,8 +469,8 @@ // Take file number and line/column from the row. const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex]; DILineInfo Result; - getFileNameForUnit(CU, LineTable, Row.File, Spec.FLIKind, - Result.FileName); + LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(), + Spec.FLIKind, Result.FileName); Result.FunctionName = FunctionName; Result.Line = Row.Line; Result.Column = Row.Column; @@ -538,10 +498,10 @@ if (Spec.FLIKind != FileLineInfoKind::None) { DILineInfo Frame; LineTable = getLineTableForUnit(CU); - if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, - Frame)) { + if (LineTable && + LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), + Spec.FLIKind, Frame)) InliningInfo.addFrame(Frame); - } } return InliningInfo; } @@ -560,13 +520,15 @@ // compile unit and fetch file/line info from it. LineTable = getLineTableForUnit(CU); // For the topmost routine, get file/line info from line table. - getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, - 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. - getFileNameForUnit(CU, LineTable, CallFile, Spec.FLIKind, - Frame.FileName); + if (LineTable) + LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(), + Spec.FLIKind, Frame.FileName); Frame.Line = CallLine; Frame.Column = CallColumn; } Index: lib/DebugInfo/DWARFDebugLine.h =================================================================== --- lib/DebugInfo/DWARFDebugLine.h +++ lib/DebugInfo/DWARFDebugLine.h @@ -20,6 +20,8 @@ namespace llvm { class raw_ostream; +class DWARFUnit; +class DWARFCompileUnit; class DWARFDebugLine { public: @@ -179,10 +181,14 @@ // Extracts filename by its index in filename table in prologue. // Returns true on success. - bool getFileNameByIndex(uint64_t FileIndex, + bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const; + bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, + DILineInfoSpecifier::FileLineInfoKind Kind, + DILineInfo &Result) const; + void dump(raw_ostream &OS) const; void clear(); Index: lib/DebugInfo/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARFDebugLine.cpp @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugLine.h" +#include "DWARFCompileUnit.h" +#include "DWARFUnit.h" +#include "llvm/Config/config.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" @@ -644,6 +647,7 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, + const char *CompDir, FileLineInfoKind Kind, std::string &Result) const { if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || @@ -651,20 +655,51 @@ return false; const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; const char *FileName = Entry.Name; + if (Kind != FileLineInfoKind::AbsoluteFilePath || sys::path::is_absolute(FileName)) { Result = FileName; return true; } + SmallString<16> FilePath; uint64_t IncludeDirIndex = Entry.DirIdx; + const char *IncludeDir = ""; + const char *CompilationDir = ""; + // Be defensive about the contents of Entry. if (IncludeDirIndex > 0 && - IncludeDirIndex <= Prologue.IncludeDirectories.size()) { - const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; - sys::path::append(FilePath, IncludeDir); - } - sys::path::append(FilePath, FileName); + IncludeDirIndex <= Prologue.IncludeDirectories.size()) + IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; + + // We may still need to append compilation directory of compile unit. + // We know that FileName is not absolute, the only way to have an + // absolute path at this point would be if IncludeDir is absolute. + if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath && + sys::path::is_relative(IncludeDir)) + CompilationDir = CompDir; + + // sys::path::append skips empty strings. + sys::path::append(FilePath, CompilationDir, IncludeDir, FileName); Result = FilePath.str(); + + return true; +} + +bool +DWARFDebugLine::LineTable::getFileLineInfoForAddress(uint64_t Address, + const char *CompDir, + FileLineInfoKind Kind, + DILineInfo &Result) const { + // Get the index of row we're looking for in the line table. + uint32_t RowIndex = lookupAddress(Address); + if (RowIndex == -1U) + return false; + // Take file number and line/column from the row. + const DWARFDebugLine::Row &Row = Rows[RowIndex]; + if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName)) + return false; + Result.Line = Row.Line; + Result.Column = Row.Column; return true; }