1
//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===/
10
#include "llvm/DebugInfo/PDB/PDBContext.h"
11
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
12
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
13
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
14
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
15
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
16
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
17
#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
18
#include "llvm/Object/COFF.h"
21
using namespace llvm::object;
23
PDBContext::PDBContext(const COFFObjectFile &Object,
24
std::unique_ptr<IPDBSession> PDBSession,
26
: DIContext(CK_PDB), Session(std::move(PDBSession)) {
27
if (!RelativeAddress) {
28
uint64_t ImageBase = 0;
30
const pe32plus_header *Header = nullptr;
31
Object.getPE32PlusHeader(Header);
33
ImageBase = Header->ImageBase;
35
const pe32_header *Header = nullptr;
36
Object.getPE32Header(Header);
38
ImageBase = static_cast<uint64_t>(Header->ImageBase);
40
Session->setLoadAddress(ImageBase);
44
void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
46
DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
47
DILineInfoSpecifier Specifier) {
49
Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
52
std::unique_ptr<PDBSymbol> Symbol =
53
Session->findSymbolByAddress(Address, PDB_SymType::None);
54
if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
55
Length = Func->getLength();
56
} else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
57
Length = Data->getLength();
60
// If we couldn't find a symbol, then just assume 1 byte, so that we get
61
// only the line number of the first instruction.
62
auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
63
if (!LineNumbers || LineNumbers->getChildCount() == 0)
66
auto LineInfo = LineNumbers->getNext();
68
auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
71
Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
72
Result.FileName = SourceFile->getFileName();
73
Result.Column = LineInfo->getColumnNumber();
74
Result.Line = LineInfo->getLineNumber();
79
PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
80
DILineInfoSpecifier Specifier) {
82
return DILineInfoTable();
84
DILineInfoTable Table;
85
auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
86
if (!LineNumbers || LineNumbers->getChildCount() == 0)
89
while (auto LineInfo = LineNumbers->getNext()) {
90
DILineInfo LineEntry =
91
getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
92
Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
98
PDBContext::getInliningInfoForAddress(uint64_t Address,
99
DILineInfoSpecifier Specifier) {
100
DIInliningInfo InlineInfo;
101
DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
102
InlineInfo.addFrame(Frame);
106
std::string PDBContext::getFunctionName(uint64_t Address,
107
DINameKind NameKind) const {
108
if (NameKind == DINameKind::None)
109
return std::string();
111
if (NameKind == DINameKind::LinkageName) {
112
// It is not possible to get the mangled linkage name through a
113
// PDBSymbolFunc. For that we have to specifically request a
114
// PDBSymbolPublicSymbol.
116
Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
117
if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get()))
118
return PS->getName();
122
Session->findSymbolByAddress(Address, PDB_SymType::Function);
124
// This could happen either if there was no public symbol (e.g. not
125
// external) or the user requested the short name. In the former case,
126
// although they technically requested the linkage name, if the linkage
127
// name is not available we fallback to at least returning a non-empty
129
if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get()))
130
return Func->getName();
132
return std::string();