LLVM  7.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 
168 bool NativeSession::setLoadAddress(uint64_t Address) { return false; }
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 
189  uint32_t &Offset) const {
190  return false;
191 }
192 
194  uint32_t &Offset) const {
195  return false;
196 }
197 
198 std::unique_ptr<PDBSymbol>
200  return nullptr;
201 }
202 
203 std::unique_ptr<PDBSymbol>
205  return nullptr;
206 }
207 
208 std::unique_ptr<PDBSymbol>
210  PDB_SymType Type) const {
211  return nullptr;
212 }
213 
214 std::unique_ptr<IPDBEnumLineNumbers>
216  const IPDBSourceFile &File) const {
217  return nullptr;
218 }
219 
220 std::unique_ptr<IPDBEnumLineNumbers>
222  uint32_t Length) const {
223  return nullptr;
224 }
225 
226 std::unique_ptr<IPDBEnumLineNumbers>
228  return nullptr;
229 }
230 
231 std::unique_ptr<IPDBEnumLineNumbers>
233  uint32_t Length) const {
234  return nullptr;
235 }
236 
237 std::unique_ptr<IPDBEnumSourceFiles>
239  StringRef Pattern,
240  PDB_NameSearchFlags Flags) const {
241  return nullptr;
242 }
243 
244 std::unique_ptr<IPDBSourceFile>
246  StringRef Pattern,
247  PDB_NameSearchFlags Flags) const {
248  return nullptr;
249 }
250 
251 std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
253  PDB_NameSearchFlags Flags) const {
254  return nullptr;
255 }
256 
257 std::unique_ptr<PDBSymbolCompiland>
259  PDB_NameSearchFlags Flags) const {
260  return nullptr;
261 }
262 
263 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
264  return nullptr;
265 }
266 
267 std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
268  const PDBSymbolCompiland &Compiland) const {
269  return nullptr;
270 }
271 
272 std::unique_ptr<IPDBSourceFile>
274  return nullptr;
275 }
276 
277 std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
278  return nullptr;
279 }
280 
281 std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
282  return nullptr;
283 }
284 
285 std::unique_ptr<IPDBEnumInjectedSources>
287  return nullptr;
288 }
289 
290 std::unique_ptr<IPDBEnumSectionContribs>
292  return nullptr;
293 }
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:250
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, uint32_t Length) const override
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:241
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
std::unique_ptr< IPDBEnumSectionContribs > getSectionContribs() const override
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:34
SimpleTypeKind getSimpleKind() const
Definition: TypeIndex.h:127
PDB_NameSearchFlags
Defines flags used for enumerating child symbols.
Definition: PDBTypes.h:97
constexpr int I
Definition: RawTypes.h:346
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:132
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:921
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
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override
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:179
* 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
std::unique_ptr< PDBSymbol > findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const override
uint64_t getLoadAddress() const override
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:936
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:970
std::unique_ptr< PDBSymbol > findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type) const override
Basic Register Allocator
static ErrorSuccess success()
Create a success value.
Definition: Error.h:321
std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override
std::unique_ptr< IPDBEnumSymbols > createTypeEnumerator(codeview::TypeLeafKind Kind)
std::unique_ptr< PDBSymbolExe > getGlobalScope() override
bool setLoadAddress(uint64_t Address) override
std::unique_ptr< PDBSymbolCompiland > createCompilandSymbol(DbiModuleDescriptor MI)
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:259
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())
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)
bool addressForRVA(uint32_t RVA, uint32_t &Section, uint32_t &Offset) const override
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
bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override
std::unique_ptr< IPDBEnumInjectedSources > getInjectedSources() const override
std::unique_ptr< PDBSymbol > getSymbolById(uint32_t SymbolId) const override