blob: d7be2d576c2dd7c67913a6f464529eb45d41f4dc [file] [log] [blame]
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +00001//===- NativeSession.cpp - Native implementation of IPDBSession -*- 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/Native/NativeSession.h"
11
12#include "llvm/ADT/STLExtras.h"
Adrian McCarthy8d090fc2017-07-12 19:38:11 +000013#include "llvm/DebugInfo/CodeView/TypeIndex.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000014#include "llvm/DebugInfo/PDB/GenericError.h"
15#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
16#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
Adrian McCarthy8d090fc2017-07-12 19:38:11 +000017#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
Adrian McCarthybf0afc32017-06-28 22:47:40 +000018#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
Adrian McCarthyb41f03e2017-08-04 22:37:58 +000019#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h"
20#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
Adrian McCarthy4d93d662017-03-29 19:27:08 +000021#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000022#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
23#include "llvm/DebugInfo/PDB/Native/RawError.h"
Adrian McCarthyb41f03e2017-08-04 22:37:58 +000024#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000025#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
26#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
Adrian McCarthyb41f03e2017-08-04 22:37:58 +000027#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000028#include "llvm/Support/Allocator.h"
Zachary Turnerd9dc2822017-03-02 20:52:51 +000029#include "llvm/Support/BinaryByteStream.h"
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000030#include "llvm/Support/Error.h"
31#include "llvm/Support/ErrorOr.h"
32#include "llvm/Support/MemoryBuffer.h"
Adrian McCarthybf0afc32017-06-28 22:47:40 +000033
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000034#include <algorithm>
Adrian McCarthyb41f03e2017-08-04 22:37:58 +000035#include <cassert>
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000036#include <memory>
Adrian McCarthybf0afc32017-06-28 22:47:40 +000037#include <utility>
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000038
39using namespace llvm;
40using namespace llvm::msf;
41using namespace llvm::pdb;
42
Adrian McCarthy8d090fc2017-07-12 19:38:11 +000043namespace {
44// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
45// to instantiate a NativeBuiltinSymbol for that type.
Reid Kleckner0962cb22017-07-12 19:46:35 +000046static const struct BuiltinTypeEntry {
Adrian McCarthy8d090fc2017-07-12 19:38:11 +000047 codeview::SimpleTypeKind Kind;
48 PDB_BuiltinType Type;
49 uint32_t Size;
50} BuiltinTypes[] = {
51 {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
52 {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
53 {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
54 {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
55 {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
56 {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
57 {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
58 {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
59 {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
60 // This table can be grown as necessary, but these are the only types we've
61 // needed so far.
62};
63} // namespace
64
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000065NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
66 std::unique_ptr<BumpPtrAllocator> Allocator)
67 : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
68
69NativeSession::~NativeSession() = default;
70
71Error NativeSession::createFromPdb(StringRef Path,
72 std::unique_ptr<IPDBSession> &Session) {
73 ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
74 MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
75 /*RequiresNullTerminator=*/false);
76 if (!ErrorOrBuffer)
77 return make_error<GenericError>(generic_error_code::invalid_path);
78
79 std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
Zachary Turner695ed562017-02-28 00:04:07 +000080 auto Stream = llvm::make_unique<MemoryBufferByteStream>(
81 std::move(Buffer), llvm::support::little);
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000082
83 auto Allocator = llvm::make_unique<BumpPtrAllocator>();
Zachary Turner7b327d02017-02-16 23:35:45 +000084 auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +000085 if (auto EC = File->parseFileHeaders())
86 return EC;
87 if (auto EC = File->parseStreamData())
88 return EC;
89
90 Session =
91 llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
92
93 return Error::success();
94}
95
96Error NativeSession::createFromExe(StringRef Path,
97 std::unique_ptr<IPDBSession> &Session) {
98 return make_error<RawError>(raw_error_code::feature_unsupported);
99}
100
Adrian McCarthybf0afc32017-06-28 22:47:40 +0000101std::unique_ptr<PDBSymbolCompiland>
102NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000103 const auto Id = static_cast<SymIndexId>(SymbolCache.size());
Adrian McCarthybf0afc32017-06-28 22:47:40 +0000104 SymbolCache.push_back(
105 llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
106 return llvm::make_unique<PDBSymbolCompiland>(
107 *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
108}
109
Adrian McCarthyb41f03e2017-08-04 22:37:58 +0000110std::unique_ptr<PDBSymbolTypeEnum>
111NativeSession::createEnumSymbol(codeview::TypeIndex Index) {
112 const auto Id = findSymbolByTypeIndex(Index);
113 return llvm::make_unique<PDBSymbolTypeEnum>(
114 *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
115}
116
117std::unique_ptr<IPDBEnumSymbols>
118NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) {
119 auto Tpi = Pdb->getPDBTpiStream();
120 if (!Tpi) {
121 consumeError(Tpi.takeError());
122 return nullptr;
123 }
124 auto &Types = Tpi->typeCollection();
125 return std::unique_ptr<IPDBEnumSymbols>(
126 new NativeEnumTypes(*this, Types, codeview::LF_ENUM));
127}
128
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000129SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) {
130 // First see if it's already in our cache.
131 const auto Entry = TypeIndexToSymbolId.find(Index);
132 if (Entry != TypeIndexToSymbolId.end())
133 return Entry->second;
134
135 // Symbols for built-in types are created on the fly.
136 if (Index.isSimple()) {
137 // FIXME: We will eventually need to handle pointers to other simple types,
138 // which are still simple types in the world of CodeView TypeIndexes.
139 if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
140 return 0;
141 const auto Kind = Index.getSimpleKind();
Reid Kleckner0962cb22017-07-12 19:46:35 +0000142 const auto It =
143 std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes),
144 [Kind](const BuiltinTypeEntry &Builtin) {
145 return Builtin.Kind == Kind;
146 });
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000147 if (It == std::end(BuiltinTypes))
148 return 0;
149 SymIndexId Id = SymbolCache.size();
150 SymbolCache.emplace_back(
Reid Kleckner0962cb22017-07-12 19:46:35 +0000151 llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000152 TypeIndexToSymbolId[Index] = Id;
153 return Id;
154 }
155
Adrian McCarthyb41f03e2017-08-04 22:37:58 +0000156 // We need to instantiate and cache the desired type symbol.
157 auto Tpi = Pdb->getPDBTpiStream();
158 if (!Tpi) {
159 consumeError(Tpi.takeError());
160 return 0;
161 }
162 auto &Types = Tpi->typeCollection();
163 const auto &I = Types.getType(Index);
164 const auto Id = static_cast<SymIndexId>(SymbolCache.size());
165 // TODO(amccarth): Make this handle all types, not just LF_ENUMs.
166 assert(I.kind() == codeview::LF_ENUM);
167 SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I));
168 TypeIndexToSymbolId[Index] = Id;
169 return Id;
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000170}
171
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +0000172uint64_t NativeSession::getLoadAddress() const { return 0; }
173
174void NativeSession::setLoadAddress(uint64_t Address) {}
175
Adrian McCarthy6a4b0802017-06-22 18:42:23 +0000176std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
Adrian McCarthy8d090fc2017-07-12 19:38:11 +0000177 const auto Id = static_cast<SymIndexId>(SymbolCache.size());
Adrian McCarthybf0afc32017-06-28 22:47:40 +0000178 SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
179 auto RawSymbol = SymbolCache[Id]->clone();
Adrian McCarthy649b8e02017-02-24 00:10:47 +0000180 auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
181 std::unique_ptr<PDBSymbolExe> ExeSymbol(
Adrian McCarthy6a4b0802017-06-22 18:42:23 +0000182 static_cast<PDBSymbolExe *>(PdbSymbol.release()));
Adrian McCarthy649b8e02017-02-24 00:10:47 +0000183 return ExeSymbol;
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +0000184}
185
186std::unique_ptr<PDBSymbol>
187NativeSession::getSymbolById(uint32_t SymbolId) const {
Adrian McCarthybf0afc32017-06-28 22:47:40 +0000188 // If the caller has a SymbolId, it'd better be in our SymbolCache.
189 return SymbolId < SymbolCache.size()
190 ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
191 : nullptr;
Adrian McCarthy6b6b8c42017-01-25 22:38:55 +0000192}
193
194std::unique_ptr<PDBSymbol>
195NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
196 return nullptr;
197}
198
199std::unique_ptr<IPDBEnumLineNumbers>
200NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
201 const IPDBSourceFile &File) const {
202 return nullptr;
203}
204
205std::unique_ptr<IPDBEnumLineNumbers>
206NativeSession::findLineNumbersByAddress(uint64_t Address,
207 uint32_t Length) const {
208 return nullptr;
209}
210
211std::unique_ptr<IPDBEnumSourceFiles>
212NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
213 StringRef Pattern,
214 PDB_NameSearchFlags Flags) const {
215 return nullptr;
216}
217
218std::unique_ptr<IPDBSourceFile>
219NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
220 StringRef Pattern,
221 PDB_NameSearchFlags Flags) const {
222 return nullptr;
223}
224
225std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
226NativeSession::findCompilandsForSourceFile(StringRef Pattern,
227 PDB_NameSearchFlags Flags) const {
228 return nullptr;
229}
230
231std::unique_ptr<PDBSymbolCompiland>
232NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
233 PDB_NameSearchFlags Flags) const {
234 return nullptr;
235}
236
237std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
238 return nullptr;
239}
240
241std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
242 const PDBSymbolCompiland &Compiland) const {
243 return nullptr;
244}
245
246std::unique_ptr<IPDBSourceFile>
247NativeSession::getSourceFileById(uint32_t FileId) const {
248 return nullptr;
249}
250
251std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
252 return nullptr;
253}