LLVM  3.7.0
DIASession.cpp
Go to the documentation of this file.
1 //===- DIASession.cpp - DIA 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/ADT/STLExtras.h"
20 
21 using namespace llvm;
22 
23 namespace {}
24 
25 DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
26 
28  std::unique_ptr<IPDBSession> &Session) {
29  CComPtr<IDiaDataSource> DiaDataSource;
30  CComPtr<IDiaSession> DiaSession;
31 
32  // We assume that CoInitializeEx has already been called by the executable.
33  HRESULT Result = ::CoCreateInstance(
34  CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
35  reinterpret_cast<LPVOID *>(&DiaDataSource));
36  if (FAILED(Result))
38 
40  if (!llvm::convertUTF8ToUTF16String(Path, Path16))
42 
43  const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
44  if (FAILED(Result = DiaDataSource->loadDataFromPdb(Path16Str))) {
45  if (Result == E_PDB_NOT_FOUND)
47  else if (Result == E_PDB_FORMAT)
49  else if (Result == E_INVALIDARG)
51  else if (Result == E_UNEXPECTED)
53  else
55  }
56 
57  if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
58  if (Result == E_OUTOFMEMORY)
60  else
62  }
63 
64  Session.reset(new DIASession(DiaSession));
66 }
67 
69  std::unique_ptr<IPDBSession> &Session) {
70  CComPtr<IDiaDataSource> DiaDataSource;
71  CComPtr<IDiaSession> DiaSession;
72 
73  // We assume that CoInitializeEx has already been called by the executable.
74  HRESULT Result = ::CoCreateInstance(
75  CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
76  reinterpret_cast<LPVOID *>(&DiaDataSource));
77  if (FAILED(Result))
79 
81  if (!llvm::convertUTF8ToUTF16String(Path, Path16))
83 
84  const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
85  if (FAILED(Result =
86  DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) {
87  if (Result == E_PDB_NOT_FOUND)
89  else if (Result == E_PDB_FORMAT)
91  else if (Result == E_PDB_INVALID_SIG || Result == E_PDB_INVALID_AGE)
93  else if (Result == E_INVALIDARG)
95  else if (Result == E_UNEXPECTED)
97  else
99  }
100 
101  if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
102  if (Result == E_OUTOFMEMORY)
104  else
106  }
107 
108  Session.reset(new DIASession(DiaSession));
109  return PDB_ErrorCode::Success;
110 }
111 
112 uint64_t DIASession::getLoadAddress() const {
113  uint64_t LoadAddress;
114  bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
115  return (success) ? LoadAddress : 0;
116 }
117 
119  Session->put_loadAddress(Address);
120 }
121 
122 std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
123  CComPtr<IDiaSymbol> GlobalScope;
124  if (S_OK != Session->get_globalScope(&GlobalScope))
125  return nullptr;
126 
127  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
128  auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
129  std::unique_ptr<PDBSymbolExe> ExeSymbol(
130  static_cast<PDBSymbolExe *>(PdbSymbol.release()));
131  return ExeSymbol;
132 }
133 
134 std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
135  CComPtr<IDiaSymbol> LocatedSymbol;
136  if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
137  return nullptr;
138 
139  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
140  return PDBSymbol::create(*this, std::move(RawSymbol));
141 }
142 
143 std::unique_ptr<PDBSymbol>
145  enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
146 
147  CComPtr<IDiaSymbol> Symbol;
148  if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) {
149  ULONGLONG LoadAddr = 0;
150  if (S_OK != Session->get_loadAddress(&LoadAddr))
151  return nullptr;
152  DWORD RVA = static_cast<DWORD>(Address - LoadAddr);
153  if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
154  return nullptr;
155  }
156  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
157  return PDBSymbol::create(*this, std::move(RawSymbol));
158 }
159 
160 std::unique_ptr<IPDBEnumLineNumbers>
161 DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
162  CComPtr<IDiaEnumLineNumbers> LineNumbers;
163  if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers))
164  return nullptr;
165 
166  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
167 }
168 
169 std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
170  CComPtr<IDiaEnumSourceFiles> Files;
171  if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
172  return nullptr;
173 
174  return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
175 }
176 
177 std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
178  const PDBSymbolCompiland &Compiland) const {
179  CComPtr<IDiaEnumSourceFiles> Files;
180 
181  const DIARawSymbol &RawSymbol =
182  static_cast<const DIARawSymbol &>(Compiland.getRawSymbol());
183  if (S_OK !=
184  Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
185  return nullptr;
186 
187  return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
188 }
189 
190 std::unique_ptr<IPDBSourceFile>
191 DIASession::getSourceFileById(uint32_t FileId) const {
192  CComPtr<IDiaSourceFile> LocatedFile;
193  if (S_OK != Session->findFileById(FileId, &LocatedFile))
194  return nullptr;
195 
196  return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
197 }
198 
199 std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
200  CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
201  if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
202  return nullptr;
203 
204  return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
205 }
const IPDBRawSymbol & getRawSymbol() const
Definition: PDBSymbol.h:83
std::unique_ptr< IPDBEnumSourceFiles > getAllSourceFiles() const override
Definition: DIASession.cpp:169
std::unique_ptr< PDBSymbol > getSymbolById(uint32_t SymbolId) const override
Definition: DIASession.cpp:134
std::unique_ptr< PDBSymbol > findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override
Definition: DIASession.cpp:144
static std::unique_ptr< PDBSymbol > create(const IPDBSession &PDBSession, std::unique_ptr< IPDBRawSymbol > Symbol)
Definition: PDBSymbol.cpp:65
std::unique_ptr< IPDBSourceFile > getSourceFileById(uint32_t FileId) const override
Definition: DIASession.cpp:191
bool convertUTF8ToUTF16String(StringRef SrcUTF8, SmallVectorImpl< UTF16 > &DstUTF16)
CComPtr< IDiaSymbol > getDiaSymbol() const
Definition: DIARawSymbol.h:24
PDB_ErrorCode
Definition: PDBTypes.h:423
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void setLoadAddress(uint64_t Address) override
Definition: DIASession.cpp:118
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override
Definition: DIASession.cpp:161
std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override
Definition: DIASession.cpp:177
static PDB_ErrorCode createFromPdb(StringRef Path, std::unique_ptr< IPDBSession > &Session)
Definition: DIASession.cpp:27
std::unique_ptr< IPDBEnumDataStreams > getDebugStreams() const override
Definition: DIASession.cpp:199
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
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:270
uint64_t getLoadAddress() const override
Definition: DIASession.cpp:112
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:134
std::unique_ptr< PDBSymbolExe > getGlobalScope() const override
Definition: DIASession.cpp:122
DIASession(CComPtr< IDiaSession > DiaSession)
Definition: DIASession.cpp:25
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
static PDB_ErrorCode createFromExe(StringRef Path, std::unique_ptr< IPDBSession > &Session)
Definition: DIASession.cpp:68