1cffff26bSZachary Turner //===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===//
2cffff26bSZachary Turner //
3cffff26bSZachary Turner //                     The LLVM Compiler Infrastructure
4cffff26bSZachary Turner //
5cffff26bSZachary Turner // This file is distributed under the University of Illinois Open Source
6cffff26bSZachary Turner // License. See LICENSE.TXT for details.
7cffff26bSZachary Turner //
8cffff26bSZachary Turner //===----------------------------------------------------------------------===//
9cffff26bSZachary Turner 
10*be6d1e49SZachary Turner #include "llvm/ADT/STLExtras.h"
11a5549178SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
12a5549178SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
13a5549178SZachary Turner 
14cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
15a5549178SZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
16cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
17cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
18cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
19cffff26bSZachary Turner #include "llvm/Support/ConvertUTF.h"
20cffff26bSZachary Turner 
21cffff26bSZachary Turner using namespace llvm;
22cffff26bSZachary Turner 
23cffff26bSZachary Turner namespace {}
24cffff26bSZachary Turner 
25cffff26bSZachary Turner DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
26cffff26bSZachary Turner 
27cffff26bSZachary Turner DIASession *DIASession::createFromPdb(StringRef Path) {
28cffff26bSZachary Turner   CComPtr<IDiaDataSource> DataSource;
29cffff26bSZachary Turner   CComPtr<IDiaSession> Session;
30cffff26bSZachary Turner 
31cffff26bSZachary Turner   // We assume that CoInitializeEx has already been called by the executable.
32cffff26bSZachary Turner   HRESULT Result = ::CoCreateInstance(CLSID_DiaSource, nullptr,
33cffff26bSZachary Turner                                       CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
34cffff26bSZachary Turner                                       reinterpret_cast<LPVOID *>(&DataSource));
35cffff26bSZachary Turner   if (FAILED(Result))
36cffff26bSZachary Turner     return nullptr;
37cffff26bSZachary Turner 
38cffff26bSZachary Turner   llvm::SmallVector<UTF16, 128> Path16;
39cffff26bSZachary Turner   if (!llvm::convertUTF8ToUTF16String(Path, Path16))
40cffff26bSZachary Turner     return nullptr;
41cffff26bSZachary Turner 
42cffff26bSZachary Turner   const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
43cffff26bSZachary Turner   if (FAILED(DataSource->loadDataFromPdb(Path16Str)))
44cffff26bSZachary Turner     return nullptr;
45cffff26bSZachary Turner 
46cffff26bSZachary Turner   if (FAILED(DataSource->openSession(&Session)))
47cffff26bSZachary Turner     return nullptr;
48cffff26bSZachary Turner   return new DIASession(Session);
49cffff26bSZachary Turner }
50cffff26bSZachary Turner 
51cffff26bSZachary Turner uint64_t DIASession::getLoadAddress() const {
52cffff26bSZachary Turner   uint64_t LoadAddress;
53cffff26bSZachary Turner   bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
54cffff26bSZachary Turner   return (success) ? LoadAddress : 0;
55cffff26bSZachary Turner }
56cffff26bSZachary Turner 
57cffff26bSZachary Turner void DIASession::setLoadAddress(uint64_t Address) {
58cffff26bSZachary Turner   Session->put_loadAddress(Address);
59cffff26bSZachary Turner }
60cffff26bSZachary Turner 
61cffff26bSZachary Turner std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
62cffff26bSZachary Turner   CComPtr<IDiaSymbol> GlobalScope;
63cffff26bSZachary Turner   if (S_OK != Session->get_globalScope(&GlobalScope))
64cffff26bSZachary Turner     return nullptr;
65cffff26bSZachary Turner 
66*be6d1e49SZachary Turner   auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
67cffff26bSZachary Turner   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
68cffff26bSZachary Turner   std::unique_ptr<PDBSymbolExe> ExeSymbol(
69cffff26bSZachary Turner       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
70cffff26bSZachary Turner   return ExeSymbol;
71cffff26bSZachary Turner }
72cffff26bSZachary Turner 
73cffff26bSZachary Turner std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
74cffff26bSZachary Turner   CComPtr<IDiaSymbol> LocatedSymbol;
75cffff26bSZachary Turner   if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
76cffff26bSZachary Turner     return nullptr;
77cffff26bSZachary Turner 
78*be6d1e49SZachary Turner   auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
79cffff26bSZachary Turner   return PDBSymbol::create(*this, std::move(RawSymbol));
80cffff26bSZachary Turner }
81cffff26bSZachary Turner 
82a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
83a5549178SZachary Turner   CComPtr<IDiaEnumSourceFiles> Files;
84a5549178SZachary Turner   if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
85a5549178SZachary Turner     return nullptr;
86a5549178SZachary Turner 
87*be6d1e49SZachary Turner   return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
88a5549178SZachary Turner }
89a5549178SZachary Turner 
90a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
91a5549178SZachary Turner     const PDBSymbolCompiland &Compiland) const {
92a5549178SZachary Turner   CComPtr<IDiaEnumSourceFiles> Files;
93a5549178SZachary Turner 
94a5549178SZachary Turner   const DIARawSymbol &RawSymbol =
95a5549178SZachary Turner       static_cast<const DIARawSymbol &>(Compiland.getRawSymbol());
96a5549178SZachary Turner   if (S_OK !=
97a5549178SZachary Turner       Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
98a5549178SZachary Turner     return nullptr;
99a5549178SZachary Turner 
100*be6d1e49SZachary Turner   return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
101a5549178SZachary Turner }
102a5549178SZachary Turner 
103cffff26bSZachary Turner std::unique_ptr<IPDBSourceFile>
104cffff26bSZachary Turner DIASession::getSourceFileById(uint32_t FileId) const {
105cffff26bSZachary Turner   CComPtr<IDiaSourceFile> LocatedFile;
106cffff26bSZachary Turner   if (S_OK != Session->findFileById(FileId, &LocatedFile))
107cffff26bSZachary Turner     return nullptr;
108cffff26bSZachary Turner 
109*be6d1e49SZachary Turner   return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
110cffff26bSZachary Turner }
111cffff26bSZachary Turner 
112cffff26bSZachary Turner std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
113cffff26bSZachary Turner   CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
114cffff26bSZachary Turner   if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
115cffff26bSZachary Turner     return nullptr;
116cffff26bSZachary Turner 
117*be6d1e49SZachary Turner   return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
118cffff26bSZachary Turner }
119