Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/PDB/PDBContext.cpp
35266 views
1
//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===/
8
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"
20
21
using namespace llvm;
22
using namespace llvm::object;
23
using namespace llvm::pdb;
24
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();
29
if (ImageBase)
30
Session->setLoadAddress(ImageBase.get());
31
}
32
33
void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
34
35
DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
36
DILineInfoSpecifier Specifier) {
37
DILineInfo Result;
38
Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);
39
40
uint32_t Length = 1;
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();
47
}
48
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)
53
return Result;
54
55
auto LineInfo = LineNumbers->getNext();
56
assert(LineInfo);
57
auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
58
59
if (SourceFile &&
60
Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
61
Result.FileName = SourceFile->getFileName();
62
Result.Column = LineInfo->getColumnNumber();
63
Result.Line = LineInfo->getLineNumber();
64
return Result;
65
}
66
67
DILineInfo
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.
71
return DILineInfo();
72
}
73
74
DILineInfoTable
75
PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
76
uint64_t Size,
77
DILineInfoSpecifier Specifier) {
78
if (Size == 0)
79
return DILineInfoTable();
80
81
DILineInfoTable Table;
82
auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);
83
if (!LineNumbers || LineNumbers->getChildCount() == 0)
84
return Table;
85
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));
90
}
91
return Table;
92
}
93
94
DIInliningInfo
95
PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
96
DILineInfoSpecifier Specifier) {
97
DIInliningInfo InlineInfo;
98
DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);
99
100
// Find the function at this address.
101
std::unique_ptr<PDBSymbol> ParentFunc =
102
Session->findSymbolByAddress(Address.Address, PDB_SymType::Function);
103
if (!ParentFunc) {
104
InlineInfo.addFrame(CurrentLine);
105
return InlineInfo;
106
}
107
108
auto Frames = ParentFunc->findInlineFramesByVA(Address.Address);
109
if (!Frames || Frames->getChildCount() == 0) {
110
InlineInfo.addFrame(CurrentLine);
111
return InlineInfo;
112
}
113
114
while (auto Frame = Frames->getNext()) {
115
uint32_t Length = 1;
116
auto LineNumbers = Frame->findInlineeLinesByVA(Address.Address, Length);
117
if (!LineNumbers || LineNumbers->getChildCount() == 0)
118
break;
119
120
std::unique_ptr<IPDBLineNumber> Line = LineNumbers->getNext();
121
assert(Line);
122
123
DILineInfo LineInfo;
124
LineInfo.FunctionName = Frame->getName();
125
auto SourceFile = Session->getSourceFileById(Line->getSourceFileId());
126
if (SourceFile &&
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);
132
}
133
134
InlineInfo.addFrame(CurrentLine);
135
return InlineInfo;
136
}
137
138
std::vector<DILocal>
139
PDBContext::getLocalsForAddress(object::SectionedAddress Address) {
140
return std::vector<DILocal>();
141
}
142
143
std::string PDBContext::getFunctionName(uint64_t Address,
144
DINameKind NameKind) const {
145
if (NameKind == DINameKind::None)
146
return std::string();
147
148
std::unique_ptr<PDBSymbol> FuncSymbol =
149
Session->findSymbolByAddress(Address, PDB_SymType::Function);
150
auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
151
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.
156
auto PublicSym =
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();
164
}
165
}
166
167
return Func ? Func->getName() : std::string();
168
}
169
170