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/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
18 #include "llvm/DebugInfo/PDB/PDBTypes.h"
19 #include "llvm/Object/COFF.h"
22 using namespace llvm::object
;
23 using namespace llvm::pdb
;
25 PDBContext::PDBContext(const COFFObjectFile
&Object
,
26 std::unique_ptr
<IPDBSession
> PDBSession
)
27 : DIContext(CK_PDB
), Session(std::move(PDBSession
)) {
28 ErrorOr
<uint64_t> ImageBase
= Object
.getImageBase();
30 Session
->setLoadAddress(ImageBase
.get());
33 void PDBContext::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
){}
35 DILineInfo
PDBContext::getLineInfoForAddress(object::SectionedAddress Address
,
36 DILineInfoSpecifier Specifier
) {
38 Result
.FunctionName
= getFunctionName(Address
.Address
, Specifier
.FNKind
);
41 std::unique_ptr
<PDBSymbol
> Symbol
=
42 Session
->findSymbolByAddress(Address
.Address
, PDB_SymType::None
);
43 if (auto Func
= dyn_cast_or_null
<PDBSymbolFunc
>(Symbol
.get())) {
44 Length
= Func
->getLength();
45 } else if (auto Data
= dyn_cast_or_null
<PDBSymbolData
>(Symbol
.get())) {
46 Length
= Data
->getLength();
49 // If we couldn't find a symbol, then just assume 1 byte, so that we get
50 // only the line number of the first instruction.
51 auto LineNumbers
= Session
->findLineNumbersByAddress(Address
.Address
, Length
);
52 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
55 auto LineInfo
= LineNumbers
->getNext();
57 auto SourceFile
= Session
->getSourceFileById(LineInfo
->getSourceFileId());
60 Specifier
.FLIKind
!= DILineInfoSpecifier::FileLineInfoKind::None
)
61 Result
.FileName
= SourceFile
->getFileName();
62 Result
.Column
= LineInfo
->getColumnNumber();
63 Result
.Line
= LineInfo
->getLineNumber();
68 PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address
) {
69 // Unimplemented. S_GDATA and S_LDATA in CodeView (used to describe global
70 // variables) aren't capable of carrying line information.
75 PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address
,
77 DILineInfoSpecifier Specifier
) {
79 return DILineInfoTable();
81 DILineInfoTable Table
;
82 auto LineNumbers
= Session
->findLineNumbersByAddress(Address
.Address
, Size
);
83 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
86 while (auto LineInfo
= LineNumbers
->getNext()) {
87 DILineInfo LineEntry
= getLineInfoForAddress(
88 {LineInfo
->getVirtualAddress(), Address
.SectionIndex
}, Specifier
);
89 Table
.push_back(std::make_pair(LineInfo
->getVirtualAddress(), LineEntry
));
95 PDBContext::getInliningInfoForAddress(object::SectionedAddress Address
,
96 DILineInfoSpecifier Specifier
) {
97 DIInliningInfo InlineInfo
;
98 DILineInfo CurrentLine
= getLineInfoForAddress(Address
, Specifier
);
100 // Find the function at this address.
101 std::unique_ptr
<PDBSymbol
> ParentFunc
=
102 Session
->findSymbolByAddress(Address
.Address
, PDB_SymType::Function
);
104 InlineInfo
.addFrame(CurrentLine
);
108 auto Frames
= ParentFunc
->findInlineFramesByVA(Address
.Address
);
109 if (!Frames
|| Frames
->getChildCount() == 0) {
110 InlineInfo
.addFrame(CurrentLine
);
114 while (auto Frame
= Frames
->getNext()) {
116 auto LineNumbers
= Frame
->findInlineeLinesByVA(Address
.Address
, Length
);
117 if (!LineNumbers
|| LineNumbers
->getChildCount() == 0)
120 std::unique_ptr
<IPDBLineNumber
> Line
= LineNumbers
->getNext();
124 LineInfo
.FunctionName
= Frame
->getName();
125 auto SourceFile
= Session
->getSourceFileById(Line
->getSourceFileId());
127 Specifier
.FLIKind
!= DILineInfoSpecifier::FileLineInfoKind::None
)
128 LineInfo
.FileName
= SourceFile
->getFileName();
129 LineInfo
.Line
= Line
->getLineNumber();
130 LineInfo
.Column
= Line
->getColumnNumber();
131 InlineInfo
.addFrame(LineInfo
);
134 InlineInfo
.addFrame(CurrentLine
);
139 PDBContext::getLocalsForAddress(object::SectionedAddress Address
) {
140 return std::vector
<DILocal
>();
143 std::string
PDBContext::getFunctionName(uint64_t Address
,
144 DINameKind NameKind
) const {
145 if (NameKind
== DINameKind::None
)
146 return std::string();
148 std::unique_ptr
<PDBSymbol
> FuncSymbol
=
149 Session
->findSymbolByAddress(Address
, PDB_SymType::Function
);
150 auto *Func
= dyn_cast_or_null
<PDBSymbolFunc
>(FuncSymbol
.get());
152 if (NameKind
== DINameKind::LinkageName
) {
153 // It is not possible to get the mangled linkage name through a
154 // PDBSymbolFunc. For that we have to specifically request a
155 // PDBSymbolPublicSymbol.
157 Session
->findSymbolByAddress(Address
, PDB_SymType::PublicSymbol
);
158 if (auto *PS
= dyn_cast_or_null
<PDBSymbolPublicSymbol
>(PublicSym
.get())) {
159 // If we also have a function symbol, prefer the use of public symbol name
160 // only if it refers to the same address. The public symbol uses the
161 // linkage name while the function does not.
162 if (!Func
|| Func
->getVirtualAddress() == PS
->getVirtualAddress())
163 return PS
->getName();
167 return Func
? Func
->getName() : std::string();