blob: a260b0ee254dad4d2517dfd0ae1b45fb989e8464 [file] [log] [blame]
Zachary Turner20dbd0d2015-04-27 17:19:51 +00001//===-- 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/PDBSymbolFunc.h"
16#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
17#include "llvm/Object/COFF.h"
18
19using namespace llvm;
20using namespace llvm::object;
21
22PDBContext::PDBContext(const COFFObjectFile &Object,
23 std::unique_ptr<IPDBSession> PDBSession)
24 : DIContext(CK_PDB), Session(std::move(PDBSession)) {
25 uint64_t ImageBase = 0;
26 if (Object.is64()) {
27 const pe32plus_header *Header = nullptr;
28 Object.getPE32PlusHeader(Header);
29 if (Header)
30 ImageBase = Header->ImageBase;
31 } else {
32 const pe32_header *Header = nullptr;
33 Object.getPE32Header(Header);
34 if (Header)
35 ImageBase = static_cast<uint64_t>(Header->ImageBase);
36 }
37 Session->setLoadAddress(ImageBase);
38}
39
40void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
41
42DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
43 DILineInfoSpecifier Specifier) {
44 auto Symbol = Session->findSymbolByAddress(Address);
45
46 uint32_t Length = 1;
47 DILineInfo Result;
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();
53
54 Length = Func->getLength();
55 } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
56 Length = Data->getLength();
57 }
58
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)
63 return Result;
64
65 auto LineInfo = LineNumbers->getNext();
66 assert(LineInfo);
67 auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
68
69 if (SourceFile &&
70 Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
71 Result.FileName = SourceFile->getFileName();
72 Result.Column = LineInfo->getColumnNumber();
73 Result.Line = LineInfo->getLineNumber();
74 return Result;
75}
76
77DILineInfoTable
78PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
79 DILineInfoSpecifier Specifier) {
80 if (Size == 0)
81 return DILineInfoTable();
82
83 DILineInfoTable Table;
84 auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
85 if (!LineNumbers || LineNumbers->getChildCount() == 0)
86 return Table;
87
88 while (auto LineInfo = LineNumbers->getNext()) {
89 DILineInfo LineEntry =
90 getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
91 Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
92 }
93 return Table;
94}
95
96DIInliningInfo
97PDBContext::getInliningInfoForAddress(uint64_t Address,
98 DILineInfoSpecifier Specifier) {
99 DIInliningInfo InlineInfo;
100 DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
101 InlineInfo.addFrame(Frame);
102 return InlineInfo;
103}