Line data Source code
1 : //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===/
9 :
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/PDBSymbolData.h"
16 : #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
17 : #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
18 : #include "llvm/Object/COFF.h"
19 :
20 : using namespace llvm;
21 : using namespace llvm::object;
22 : using namespace llvm::pdb;
23 :
24 0 : PDBContext::PDBContext(const COFFObjectFile &Object,
25 0 : std::unique_ptr<IPDBSession> PDBSession)
26 0 : : DIContext(CK_PDB), Session(std::move(PDBSession)) {
27 0 : ErrorOr<uint64_t> ImageBase = Object.getImageBase();
28 : if (ImageBase)
29 0 : Session->setLoadAddress(ImageBase.get());
30 0 : }
31 :
32 0 : void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
33 :
34 0 : DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
35 : DILineInfoSpecifier Specifier) {
36 0 : DILineInfo Result;
37 0 : Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
38 :
39 : uint32_t Length = 1;
40 : std::unique_ptr<PDBSymbol> Symbol =
41 0 : Session->findSymbolByAddress(Address, PDB_SymType::None);
42 : if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
43 0 : Length = Func->getLength();
44 : } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
45 0 : Length = Data->getLength();
46 : }
47 :
48 : // If we couldn't find a symbol, then just assume 1 byte, so that we get
49 : // only the line number of the first instruction.
50 0 : auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
51 0 : if (!LineNumbers || LineNumbers->getChildCount() == 0)
52 : return Result;
53 :
54 0 : auto LineInfo = LineNumbers->getNext();
55 : assert(LineInfo);
56 0 : auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
57 :
58 0 : if (SourceFile &&
59 0 : Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
60 0 : Result.FileName = SourceFile->getFileName();
61 0 : Result.Column = LineInfo->getColumnNumber();
62 0 : Result.Line = LineInfo->getLineNumber();
63 : return Result;
64 : }
65 :
66 : DILineInfoTable
67 0 : PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
68 : DILineInfoSpecifier Specifier) {
69 0 : if (Size == 0)
70 : return DILineInfoTable();
71 :
72 0 : DILineInfoTable Table;
73 0 : auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
74 0 : if (!LineNumbers || LineNumbers->getChildCount() == 0)
75 : return Table;
76 :
77 0 : while (auto LineInfo = LineNumbers->getNext()) {
78 : DILineInfo LineEntry =
79 0 : getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
80 0 : Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
81 : }
82 : return Table;
83 : }
84 :
85 : DIInliningInfo
86 0 : PDBContext::getInliningInfoForAddress(uint64_t Address,
87 : DILineInfoSpecifier Specifier) {
88 : DIInliningInfo InlineInfo;
89 0 : DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
90 : InlineInfo.addFrame(Frame);
91 0 : return InlineInfo;
92 : }
93 :
94 0 : std::string PDBContext::getFunctionName(uint64_t Address,
95 : DINameKind NameKind) const {
96 0 : if (NameKind == DINameKind::None)
97 : return std::string();
98 :
99 : std::unique_ptr<PDBSymbol> FuncSymbol =
100 0 : Session->findSymbolByAddress(Address, PDB_SymType::Function);
101 : auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
102 :
103 0 : if (NameKind == DINameKind::LinkageName) {
104 : // It is not possible to get the mangled linkage name through a
105 : // PDBSymbolFunc. For that we have to specifically request a
106 : // PDBSymbolPublicSymbol.
107 : auto PublicSym =
108 0 : Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
109 : if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {
110 : // If we also have a function symbol, prefer the use of public symbol name
111 : // only if it refers to the same address. The public symbol uses the
112 : // linkage name while the function does not.
113 0 : if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())
114 0 : return PS->getName();
115 : }
116 : }
117 :
118 0 : return Func ? Func->getName() : std::string();
119 : }
|