LLVM  6.0.0svn
NativeSession.cpp
Go to the documentation of this file.
1 //===- 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 
11 
12 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/Allocator.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/ErrorOr.h"
33 
34 #include <algorithm>
35 #include <cassert>
36 #include <memory>
37 #include <utility>
38 
39 using namespace llvm;
40 using namespace llvm::msf;
41 using namespace llvm::pdb;
42 
43 namespace {
44 // Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
45 // to instantiate a NativeBuiltinSymbol for that type.
46 static const struct BuiltinTypeEntry {
49  uint32_t Size;
50 } BuiltinTypes[] = {
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},
60  // This table can be grown as necessary, but these are the only types we've
61  // needed so far.
62 };
63 } // namespace
64 
65 NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
66  std::unique_ptr<BumpPtrAllocator> Allocator)
67  : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
68 
70 
71 Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
72  std::unique_ptr<IPDBSession> &Session) {
73  StringRef Path = Buffer->getBufferIdentifier();
74  auto Stream = llvm::make_unique<MemoryBufferByteStream>(
75  std::move(Buffer), llvm::support::little);
76 
77  auto Allocator = llvm::make_unique<BumpPtrAllocator>();
78  auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
79  if (auto EC = File->parseFileHeaders())
80  return EC;
81  if (auto EC = File->parseStreamData())
82  return EC;
83 
84  Session =
85  llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
86 
87  return Error::success();
88 }
89 
91  std::unique_ptr<IPDBSession> &Session) {
92  return make_error<RawError>(raw_error_code::feature_unsupported);
93 }
94 
95 std::unique_ptr<PDBSymbolCompiland>
97  const auto Id = static_cast<SymIndexId>(SymbolCache.size());
98  SymbolCache.push_back(
99  llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
100  return llvm::make_unique<PDBSymbolCompiland>(
101  *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
102 }
103 
104 std::unique_ptr<PDBSymbolTypeEnum>
106  const auto Id = findSymbolByTypeIndex(Index);
107  return llvm::make_unique<PDBSymbolTypeEnum>(
108  *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
109 }
110 
111 std::unique_ptr<IPDBEnumSymbols>
113  auto Tpi = Pdb->getPDBTpiStream();
114  if (!Tpi) {
115  consumeError(Tpi.takeError());
116  return nullptr;
117  }
118  auto &Types = Tpi->typeCollection();
119  return std::unique_ptr<IPDBEnumSymbols>(
120  new NativeEnumTypes(*this, Types, codeview::LF_ENUM));
121 }
122 
124  // First see if it's already in our cache.
125  const auto Entry = TypeIndexToSymbolId.find(Index);
126  if (Entry != TypeIndexToSymbolId.end())
127  return Entry->second;
128 
129  // Symbols for built-in types are created on the fly.
130  if (Index.isSimple()) {
131  // FIXME: We will eventually need to handle pointers to other simple types,
132  // which are still simple types in the world of CodeView TypeIndexes.
134  return 0;
135  const auto Kind = Index.getSimpleKind();
136  const auto It =
137  std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes),
138  [Kind](const BuiltinTypeEntry &Builtin) {
139  return Builtin.Kind == Kind;
140  });
141  if (It == std::end(BuiltinTypes))
142  return 0;
143  SymIndexId Id = SymbolCache.size();
144  SymbolCache.emplace_back(
145  llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
146  TypeIndexToSymbolId[Index] = Id;
147  return Id;
148  }
149 
150  // We need to instantiate and cache the desired type symbol.
151  auto Tpi = Pdb->getPDBTpiStream();
152  if (!Tpi) {
153  consumeError(Tpi.takeError());
154  return 0;
155  }
156  auto &Types = Tpi->typeCollection();
157  const auto &I = Types.getType(Index);
158  const auto Id = static_cast<SymIndexId>(SymbolCache.size());
159  // TODO(amccarth): Make this handle all types, not just LF_ENUMs.
160  assert(I.kind() == codeview::LF_ENUM);
161  SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I));
162  TypeIndexToSymbolId[Index] = Id;
163  return Id;
164 }
165 
166 uint64_t NativeSession::getLoadAddress() const { return 0; }
167 
169 
170 std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
171  const auto Id = static_cast<SymIndexId>(SymbolCache.size());
172  SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
173  auto RawSymbol = SymbolCache[Id]->clone();
174  auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
175  std::unique_ptr<PDBSymbolExe> ExeSymbol(
176  static_cast<PDBSymbolExe *>(PdbSymbol.release()));
177  return ExeSymbol;
178 }
179 
180 std::unique_ptr<PDBSymbol>
182  // If the caller has a SymbolId, it'd better be in our SymbolCache.
183  return SymbolId < SymbolCache.size()
184  ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
185  : nullptr;
186 }
187 
188 std::unique_ptr<PDBSymbol>
190  return nullptr;
191 }
192 
193 std::unique_ptr<IPDBEnumLineNumbers>
195  const IPDBSourceFile &File) const {
196  return nullptr;
197 }
198 
199 std::unique_ptr<IPDBEnumLineNumbers>
201  uint32_t Length) const {
202  return nullptr;
203 }
204 
205 std::unique_ptr<IPDBEnumSourceFiles>
207  StringRef Pattern,
208  PDB_NameSearchFlags Flags) const {
209  return nullptr;
210 }
211 
212 std::unique_ptr<IPDBSourceFile>
214  StringRef Pattern,
215  PDB_NameSearchFlags Flags) const {
216  return nullptr;
217 }
218 
219 std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
221  PDB_NameSearchFlags Flags) const {
222  return nullptr;
223 }
224 
225 std::unique_ptr<PDBSymbolCompiland>
227  PDB_NameSearchFlags Flags) const {
228  return nullptr;
229 }
230 
231 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
232  return nullptr;
233 }
234 
235 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
236  const PDBSymbolCompiland &Compiland) const {
237  return nullptr;
238 }
239 
240 std::unique_ptr<IPDBSourceFile>
242  return nullptr;
243 }
244 
245 std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
246  return nullptr;
247 }
248 
249 std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
250  return nullptr;
251 }
std::unique_ptr< IPDBEnumSourceFiles > getAllSourceFiles() const override
static Error createFromExe(StringRef Path, std::unique_ptr< IPDBSession > &Session)
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:244
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:235
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:34
SimpleTypeKind getSimpleKind() const
Definition: TypeIndex.h:125
PDB_NameSearchFlags
Defines flags used for enumerating child symbols.
Definition: PDBTypes.h:92
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
std::unique_ptr< PDBSymbol > findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override
SimpleTypeMode getSimpleMode() const
Definition: TypeIndex.h:130
IPDBSourceFile defines an interface used to represent source files whose information are stored in th...
std::unique_ptr< IPDBEnumSourceFiles > findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
Definition: BitVector.h:920
static std::unique_ptr< PDBSymbol > create(const IPDBSession &PDBSession, std::unique_ptr< IPDBRawSymbol > Symbol)
Definition: PDBSymbol.cpp:67
std::unique_ptr< IPDBEnumTables > getEnumTables() const override
std::unique_ptr< PDBSymbolTypeEnum > createEnumSymbol(codeview::TypeIndex Index)
A 32-bit type reference.
Definition: TypeIndex.h:96
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx.
Definition: PDBTypes.h:162
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
uint64_t getLoadAddress() const override
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:962
Basic Register Allocator
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override
std::unique_ptr< IPDBEnumSymbols > createTypeEnumerator(codeview::TypeLeafKind Kind)
std::unique_ptr< PDBSymbolExe > getGlobalScope() override
std::unique_ptr< PDBSymbolCompiland > createCompilandSymbol(DbiModuleDescriptor MI)
#define I(x, y, z)
Definition: MD5.cpp:58
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override
std::unique_ptr< PDBSymbolCompiland > findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
std::unique_ptr< IPDBSourceFile > getSourceFileById(uint32_t FileId) const override
PDB_BuiltinType
These values correspond to the Basictype enumeration, and are documented here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx.
Definition: PDBTypes.h:228
std::unique_ptr< IPDBEnumChildren< PDBSymbolCompiland > > findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
Provides ErrorOr<T> smart pointer.
std::unique_ptr< IPDBSourceFile > findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void setLoadAddress(uint64_t Address) override
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI)
static Error createFromPdb(std::unique_ptr< MemoryBuffer > MB, std::unique_ptr< IPDBSession > &Session)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
std::unique_ptr< IPDBEnumDataStreams > getDebugStreams() const override
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:795
std::unique_ptr< PDBSymbol > getSymbolById(uint32_t SymbolId) const override