diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h index f105526adf5618..a7ce82c70b08cb 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h @@ -19,7 +19,8 @@ namespace pdb { class NativeLineNumber : public IPDBLineNumber { public: explicit NativeLineNumber(const NativeSession &Session, - const codeview::LineInfo Line, uint32_t Length, + const codeview::LineInfo Line, + uint32_t ColumnNumber, uint32_t Length, uint32_t Section, uint32_t Offset, uint32_t SrcFileId); @@ -39,6 +40,7 @@ class NativeLineNumber : public IPDBLineNumber { private: const NativeSession &Session; const codeview::LineInfo Line; + uint32_t ColumnNumber; uint32_t Section; uint32_t Offset; uint32_t Length; diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h index e14ef320991619..90fd19a7a2fba7 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h @@ -75,6 +75,7 @@ class SymbolCache { struct LineTableEntry { uint64_t Addr; codeview::LineInfo Line; + uint32_t ColumnNumber; uint32_t FileNameIndex; bool IsTerminalEntry; }; diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp index f493c180794246..2535e09baf625f 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp @@ -13,10 +13,11 @@ using namespace llvm::pdb; NativeLineNumber::NativeLineNumber(const NativeSession &Session, const codeview::LineInfo Line, - uint32_t Section, uint32_t Offset, - uint32_t Length, uint32_t SrcFileId) - : Session(Session), Line(Line), Section(Section), Offset(Offset), - Length(Length), SrcFileId(SrcFileId) {} + uint32_t ColumnNumber, uint32_t Section, + uint32_t Offset, uint32_t Length, + uint32_t SrcFileId) + : Session(Session), Line(Line), ColumnNumber(ColumnNumber), + Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId) {} uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); } @@ -24,7 +25,7 @@ uint32_t NativeLineNumber::getLineNumberEnd() const { return Line.getEndLine(); } -uint32_t NativeLineNumber::getColumnNumber() const { return 0; } +uint32_t NativeLineNumber::getColumnNumber() const { return ColumnNumber; } uint32_t NativeLineNumber::getColumnNumberEnd() const { return 0; } diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp index 83cf77aae862a3..9f15907b519e84 100644 --- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -460,18 +460,33 @@ SymbolCache::findLineTable(uint16_t Modi) const { continue; std::vector Entries; + + // If there are column numbers, then they should be in a parallel stream + // to the line numbers. + auto ColIt = Group.Columns.begin(); + auto ColsEnd = Group.Columns.end(); + for (const LineNumberEntry &LN : Group.LineNumbers) { - LineInfo Line(LN.Flags); uint64_t VA = Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset); - Entries.push_back({VA, Line, Group.NameIndex, false}); + LineInfo Line(LN.Flags); + uint32_t ColNum = 0; + + if (Lines.hasColumnInfo() && ColIt != ColsEnd) { + ColNum = ColIt->StartColumn; + ++ColIt; + } + Entries.push_back({VA, Line, ColNum, Group.NameIndex, false}); } // Add a terminal entry line to mark the end of this subsection. - LineInfo LastLine(Group.LineNumbers.back().Flags); uint64_t VA = Session.getVAFromSectOffset( RelocSegment, RelocOffset + Lines.header()->CodeSize); - Entries.push_back({VA, LastLine, Group.NameIndex, true}); + LineInfo LastLine(Group.LineNumbers.back().Flags); + uint32_t ColNum = + (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0; + Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true}); + EntryList.push_back(Entries); } } @@ -571,8 +586,8 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const { auto ChecksumIter = ExpectedChecksums->getArray().at(LineIter->FileNameIndex); uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter); - NativeLineNumber LineNum(Session, LineIter->Line, LineSect, LineOff, - LineLength, SrcFileId); + NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber, + LineSect, LineOff, LineLength, SrcFileId); LineNumbers.push_back(LineNum); ++LineIter; } diff --git a/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.exe b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.exe new file mode 100644 index 00000000000000..1d9a40dc74e5dc Binary files /dev/null and b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.exe differ diff --git a/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.pdb b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.pdb new file mode 100644 index 00000000000000..cd1093270e8434 Binary files /dev/null and b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test-columns.pdb differ diff --git a/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test.cpp b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test.cpp index bf97594fa4c802..e1ac50f2e820f0 100644 --- a/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test.cpp +++ b/llvm/test/tools/llvm-symbolizer/pdb/Inputs/test.cpp @@ -1,5 +1,7 @@ // To generate the corresponding EXE/PDB, run: // cl /Zi test.cpp +// To generate the PDB with column numbers, run: +// clang-cl /Zi -gcolumn-info test.cpp namespace NS { struct Foo { diff --git a/llvm/test/tools/llvm-symbolizer/pdb/pdb-native-columns.test b/llvm/test/tools/llvm-symbolizer/pdb/pdb-native-columns.test new file mode 100644 index 00000000000000..a8ccc33d035740 --- /dev/null +++ b/llvm/test/tools/llvm-symbolizer/pdb/pdb-native-columns.test @@ -0,0 +1,29 @@ +RUN: echo 0x140006BA0 > %t.input +RUN: echo 0x140006C00 >> %t.input +RUN: echo 0x140006BB0 >> %t.input +RUN: echo 0x140006C10 >> %t.input +RUN: echo 0x140006C20 >> %t.input +RUN: echo 0x140006C30 >> %t.input +RUN: echo 0x140006C40 >> %t.input +RUN: echo 0x140006C70 >> %t.input +RUN: llvm-symbolizer -obj="%p/Inputs/test-columns.exe" -use-native-pdb-reader < %t.input \ +RUN: | FileCheck %s + +This tests that the symbolizer outputs column info when it is present in the pdb. + +CHECK: foo(void) +CHECK-NEXT: test.cpp:11:1 +CHECK: {{^private_symbol$}} +CHECK-NEXT: test.cpp:14:1 +CHECK: {{^main}} +CHECK-NEXT: test.cpp:16:0 +CHECK: {{^foo_cdecl$}} +CHECK-NEXT: test.cpp:25:27 +CHECK: {{^foo_stdcall$}} +CHECK-NEXT: test.cpp:26:31 +CHECK: {{^foo_fastcall$}} +CHECK-NEXT: test.cpp:27:33 +CHECK: {{^foo_vectorcall}} +CHECK-NEXT: test.cpp:28:37 +CHECK: NS::Foo::bar(void) +CHECK-NEXT: test.cpp:6:0