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 Frame
= getLineInfoForAddress(Address
, Specifier
);
90 InlineInfo
.addFrame(Frame
);
95 PDBContext::getLocalsForAddress(object::SectionedAddress Address
) {
96 return std::vector
<DILocal
>();
99 std::string
PDBContext::getFunctionName(uint64_t Address
,
100 DINameKind NameKind
) const {
101 if (NameKind
== DINameKind::None
)
102 return std::string();
104 std::unique_ptr
<PDBSymbol
> FuncSymbol
=
105 Session
->findSymbolByAddress(Address
, PDB_SymType::Function
);
106 auto *Func
= dyn_cast_or_null
<PDBSymbolFunc
>(FuncSymbol
.get());
108 if (NameKind
== DINameKind::LinkageName
) {
109 // It is not possible to get the mangled linkage name through a
110 // PDBSymbolFunc. For that we have to specifically request a
111 // PDBSymbolPublicSymbol.
113 Session
->findSymbolByAddress(Address
, PDB_SymType::PublicSymbol
);
114 if (auto *PS
= dyn_cast_or_null
<PDBSymbolPublicSymbol
>(PublicSym
.get())) {
115 // If we also have a function symbol, prefer the use of public symbol name
116 // only if it refers to the same address. The public symbol uses the
117 // linkage name while the function does not.
118 if (!Func
|| Func
->getVirtualAddress() == PS
->getVirtualAddress())
119 return PS
->getName();
123 return Func
? Func
->getName() : std::string();