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/Object/COFF.h"
20 using namespace llvm::object;
22 PDBContext::PDBContext(const COFFObjectFile &Object,
23 std::unique_ptr<IPDBSession> PDBSession)
24 : DIContext(CK_PDB), Session(std::move(PDBSession)) {
25 uint64_t ImageBase = 0;
27 const pe32plus_header *Header = nullptr;
28 Object.getPE32PlusHeader(Header);
30 ImageBase = Header->ImageBase;
32 const pe32_header *Header = nullptr;
33 Object.getPE32Header(Header);
35 ImageBase = static_cast<uint64_t>(Header->ImageBase);
37 Session->setLoadAddress(ImageBase);
40 void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
42 DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
43 DILineInfoSpecifier Specifier) {
44 auto Symbol = Session->findSymbolByAddress(Address);
48 if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
49 if (Specifier.FNKind == DINameKind::LinkageName)
50 Result.FunctionName = Func->getUndecoratedName();
51 else if (Specifier.FNKind == DINameKind::ShortName)
52 Result.FunctionName = Func->getName();
54 Length = Func->getLength();
55 } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
56 Length = Data->getLength();
59 // If we couldn't find a symbol, then just assume 1 byte, so that we get
60 // only the line number of the first instruction.
61 auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
62 if (!LineNumbers || LineNumbers->getChildCount() == 0)
65 auto LineInfo = LineNumbers->getNext();
67 auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
70 Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
71 Result.FileName = SourceFile->getFileName();
72 Result.Column = LineInfo->getColumnNumber();
73 Result.Line = LineInfo->getLineNumber();
78 PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
79 DILineInfoSpecifier Specifier) {
81 return DILineInfoTable();
83 DILineInfoTable Table;
84 auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
85 if (!LineNumbers || LineNumbers->getChildCount() == 0)
88 while (auto LineInfo = LineNumbers->getNext()) {
89 DILineInfo LineEntry =
90 getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
91 Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
97 PDBContext::getInliningInfoForAddress(uint64_t Address,
98 DILineInfoSpecifier Specifier) {
99 DIInliningInfo InlineInfo;
100 DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
101 InlineInfo.addFrame(Frame);