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