1 //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===/
9 #include "llvm/DebugInfo/PDB/PDBContext.h"
10 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
11 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
12 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
13 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
15 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
16 #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
17 #include "llvm/Object/COFF.h"
20 using namespace llvm::object
;
21 using namespace llvm::pdb
;
23 PDBContext::PDBContext(const COFFObjectFile
&Object
,
24 std::unique_ptr
<IPDBSession
> PDBSession
)
25 : DIContext(CK_PDB
), Session(std::move(PDBSession
)) {
26 ErrorOr
<uint64_t> ImageBase
= Object
.getImageBase();
28 Session
->setLoadAddress(ImageBase
.get());
31 void PDBContext::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
){}
33 DILineInfo
PDBContext::getLineInfoForAddress(object::SectionedAddress Address
,
34 DILineInfoSpecifier Specifier
) {
36 Result
.FunctionName
= getFunctionName(Address
.Address
, Specifier
.FNKind
);
39 std::unique_ptr
<PDBSymbol
> Symbol
=
40 Session
->findSymbolByAddress(Address
.Address
, PDB_SymType::None
);
41 if (auto Func
= dyn_cast_or_null
<PDBSymbolFunc
>(Symbol
.get())) {
42 Length
= Func
->getLength();
43 } else if (auto Data
= dyn_cast_or_null
<PDBSymbolData
>(Symbol
.get())) {
44 Length
= Data
->getLength();
47 // If we couldn't find a symbol, then just assume 1 byte, so that we get
48 // only the line number of the first instruction.
49 auto LineNumbers
= Session
->findLineNumbersByAddress(Address
.Address
, Length
);
50 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
53 auto LineInfo
= LineNumbers
->getNext();
55 auto SourceFile
= Session
->getSourceFileById(LineInfo
->getSourceFileId());
58 Specifier
.FLIKind
!= DILineInfoSpecifier::FileLineInfoKind::None
)
59 Result
.FileName
= SourceFile
->getFileName();
60 Result
.Column
= LineInfo
->getColumnNumber();
61 Result
.Line
= LineInfo
->getLineNumber();
66 PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address
,
68 DILineInfoSpecifier Specifier
) {
70 return DILineInfoTable();
72 DILineInfoTable Table
;
73 auto LineNumbers
= Session
->findLineNumbersByAddress(Address
.Address
, Size
);
74 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
77 while (auto LineInfo
= LineNumbers
->getNext()) {
78 DILineInfo LineEntry
= getLineInfoForAddress(
79 {LineInfo
->getVirtualAddress(), Address
.SectionIndex
}, Specifier
);
80 Table
.push_back(std::make_pair(LineInfo
->getVirtualAddress(), LineEntry
));
86 PDBContext::getInliningInfoForAddress(object::SectionedAddress Address
,
87 DILineInfoSpecifier Specifier
) {
88 DIInliningInfo InlineInfo
;
89 DILineInfo CurrentLine
= getLineInfoForAddress(Address
, Specifier
);
91 // Find the function at this address.
92 std::unique_ptr
<PDBSymbol
> ParentFunc
=
93 Session
->findSymbolByAddress(Address
.Address
, PDB_SymType::Function
);
95 InlineInfo
.addFrame(CurrentLine
);
99 auto Frames
= ParentFunc
->findInlineFramesByVA(Address
.Address
);
100 if (!Frames
|| Frames
->getChildCount() == 0) {
101 InlineInfo
.addFrame(CurrentLine
);
105 while (auto Frame
= Frames
->getNext()) {
107 auto LineNumbers
= Frame
->findInlineeLinesByVA(Address
.Address
, Length
);
108 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
111 std::unique_ptr
<IPDBLineNumber
> Line
= LineNumbers
->getNext();
115 LineInfo
.FunctionName
= Frame
->getName();
116 auto SourceFile
= Session
->getSourceFileById(Line
->getSourceFileId());
118 Specifier
.FLIKind
!= DILineInfoSpecifier::FileLineInfoKind::None
)
119 LineInfo
.FileName
= SourceFile
->getFileName();
120 LineInfo
.Line
= Line
->getLineNumber();
121 LineInfo
.Column
= Line
->getColumnNumber();
122 InlineInfo
.addFrame(LineInfo
);
125 InlineInfo
.addFrame(CurrentLine
);
130 PDBContext::getLocalsForAddress(object::SectionedAddress Address
) {
131 return std::vector
<DILocal
>();
134 std::string
PDBContext::getFunctionName(uint64_t Address
,
135 DINameKind NameKind
) const {
136 if (NameKind
== DINameKind::None
)
137 return std::string();
139 std::unique_ptr
<PDBSymbol
> FuncSymbol
=
140 Session
->findSymbolByAddress(Address
, PDB_SymType::Function
);
141 auto *Func
= dyn_cast_or_null
<PDBSymbolFunc
>(FuncSymbol
.get());
143 if (NameKind
== DINameKind::LinkageName
) {
144 // It is not possible to get the mangled linkage name through a
145 // PDBSymbolFunc. For that we have to specifically request a
146 // PDBSymbolPublicSymbol.
148 Session
->findSymbolByAddress(Address
, PDB_SymType::PublicSymbol
);
149 if (auto *PS
= dyn_cast_or_null
<PDBSymbolPublicSymbol
>(PublicSym
.get())) {
150 // If we also have a function symbol, prefer the use of public symbol name
151 // only if it refers to the same address. The public symbol uses the
152 // linkage name while the function does not.
153 if (!Func
|| Func
->getVirtualAddress() == PS
->getVirtualAddress())
154 return PS
->getName();
158 return Func
? Func
->getName() : std::string();