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 10be6d1e49SZachary Turner #include "llvm/ADT/STLExtras.h" 11cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" 12a5549178SZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h" 13cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" 14cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIASession.h" 15cffff26bSZachary Turner #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h" 1671f308adSChandler Carruth #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 1771f308adSChandler Carruth #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 18cffff26bSZachary Turner #include "llvm/Support/ConvertUTF.h" 19cffff26bSZachary Turner 20cffff26bSZachary Turner using namespace llvm; 21cffff26bSZachary Turner 22cffff26bSZachary Turner namespace {} 23cffff26bSZachary Turner 24cffff26bSZachary Turner DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {} 25cffff26bSZachary Turner 26*ccf04159SZachary Turner PDB_ErrorCode DIASession::createFromPdb(StringRef Path, 27*ccf04159SZachary Turner std::unique_ptr<IPDBSession> &Session) { 28*ccf04159SZachary Turner CComPtr<IDiaDataSource> DiaDataSource; 29*ccf04159SZachary Turner CComPtr<IDiaSession> DiaSession; 30cffff26bSZachary Turner 31cffff26bSZachary Turner // We assume that CoInitializeEx has already been called by the executable. 32*ccf04159SZachary Turner HRESULT Result = ::CoCreateInstance( 33*ccf04159SZachary Turner CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource, 34*ccf04159SZachary Turner reinterpret_cast<LPVOID *>(&DiaDataSource)); 35cffff26bSZachary Turner if (FAILED(Result)) 36*ccf04159SZachary Turner return PDB_ErrorCode::NoPdbImpl; 37cffff26bSZachary Turner 38cffff26bSZachary Turner llvm::SmallVector<UTF16, 128> Path16; 39cffff26bSZachary Turner if (!llvm::convertUTF8ToUTF16String(Path, Path16)) 40*ccf04159SZachary Turner return PDB_ErrorCode::InvalidPath; 41cffff26bSZachary Turner 42cffff26bSZachary Turner const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data()); 43*ccf04159SZachary Turner if (FAILED(Result = DiaDataSource->loadDataFromPdb(Path16Str))) { 44*ccf04159SZachary Turner if (Result == E_PDB_NOT_FOUND) 45*ccf04159SZachary Turner return PDB_ErrorCode::InvalidPath; 46*ccf04159SZachary Turner else if (Result == E_PDB_FORMAT) 47*ccf04159SZachary Turner return PDB_ErrorCode::InvalidFileFormat; 48*ccf04159SZachary Turner else if (Result == E_INVALIDARG) 49*ccf04159SZachary Turner return PDB_ErrorCode::InvalidParameter; 50*ccf04159SZachary Turner else if (Result == E_UNEXPECTED) 51*ccf04159SZachary Turner return PDB_ErrorCode::AlreadyLoaded; 52*ccf04159SZachary Turner else 53*ccf04159SZachary Turner return PDB_ErrorCode::UnknownError; 54*ccf04159SZachary Turner } 55cffff26bSZachary Turner 56*ccf04159SZachary Turner if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) { 57*ccf04159SZachary Turner if (Result == E_OUTOFMEMORY) 58*ccf04159SZachary Turner return PDB_ErrorCode::NoMemory; 59*ccf04159SZachary Turner else 60*ccf04159SZachary Turner return PDB_ErrorCode::UnknownError; 61*ccf04159SZachary Turner } 62*ccf04159SZachary Turner 63*ccf04159SZachary Turner Session.reset(new DIASession(DiaSession)); 64*ccf04159SZachary Turner return PDB_ErrorCode::Success; 65cffff26bSZachary Turner } 66cffff26bSZachary Turner 67cffff26bSZachary Turner uint64_t DIASession::getLoadAddress() const { 68cffff26bSZachary Turner uint64_t LoadAddress; 69cffff26bSZachary Turner bool success = (S_OK == Session->get_loadAddress(&LoadAddress)); 70cffff26bSZachary Turner return (success) ? LoadAddress : 0; 71cffff26bSZachary Turner } 72cffff26bSZachary Turner 73cffff26bSZachary Turner void DIASession::setLoadAddress(uint64_t Address) { 74cffff26bSZachary Turner Session->put_loadAddress(Address); 75cffff26bSZachary Turner } 76cffff26bSZachary Turner 77cffff26bSZachary Turner std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const { 78cffff26bSZachary Turner CComPtr<IDiaSymbol> GlobalScope; 79cffff26bSZachary Turner if (S_OK != Session->get_globalScope(&GlobalScope)) 80cffff26bSZachary Turner return nullptr; 81cffff26bSZachary Turner 82be6d1e49SZachary Turner auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope); 83cffff26bSZachary Turner auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); 84cffff26bSZachary Turner std::unique_ptr<PDBSymbolExe> ExeSymbol( 85cffff26bSZachary Turner static_cast<PDBSymbolExe *>(PdbSymbol.release())); 86cffff26bSZachary Turner return ExeSymbol; 87cffff26bSZachary Turner } 88cffff26bSZachary Turner 89cffff26bSZachary Turner std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const { 90cffff26bSZachary Turner CComPtr<IDiaSymbol> LocatedSymbol; 91cffff26bSZachary Turner if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol)) 92cffff26bSZachary Turner return nullptr; 93cffff26bSZachary Turner 94be6d1e49SZachary Turner auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol); 95cffff26bSZachary Turner return PDBSymbol::create(*this, std::move(RawSymbol)); 96cffff26bSZachary Turner } 97cffff26bSZachary Turner 98a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const { 99a5549178SZachary Turner CComPtr<IDiaEnumSourceFiles> Files; 100a5549178SZachary Turner if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) 101a5549178SZachary Turner return nullptr; 102a5549178SZachary Turner 103be6d1e49SZachary Turner return llvm::make_unique<DIAEnumSourceFiles>(*this, Files); 104a5549178SZachary Turner } 105a5549178SZachary Turner 106a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland( 107a5549178SZachary Turner const PDBSymbolCompiland &Compiland) const { 108a5549178SZachary Turner CComPtr<IDiaEnumSourceFiles> Files; 109a5549178SZachary Turner 110a5549178SZachary Turner const DIARawSymbol &RawSymbol = 111a5549178SZachary Turner static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); 112a5549178SZachary Turner if (S_OK != 113a5549178SZachary Turner Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files)) 114a5549178SZachary Turner return nullptr; 115a5549178SZachary Turner 116be6d1e49SZachary Turner return llvm::make_unique<DIAEnumSourceFiles>(*this, Files); 117a5549178SZachary Turner } 118a5549178SZachary Turner 119cffff26bSZachary Turner std::unique_ptr<IPDBSourceFile> 120cffff26bSZachary Turner DIASession::getSourceFileById(uint32_t FileId) const { 121cffff26bSZachary Turner CComPtr<IDiaSourceFile> LocatedFile; 122cffff26bSZachary Turner if (S_OK != Session->findFileById(FileId, &LocatedFile)) 123cffff26bSZachary Turner return nullptr; 124cffff26bSZachary Turner 125be6d1e49SZachary Turner return llvm::make_unique<DIASourceFile>(*this, LocatedFile); 126cffff26bSZachary Turner } 127cffff26bSZachary Turner 128cffff26bSZachary Turner std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const { 129cffff26bSZachary Turner CComPtr<IDiaEnumDebugStreams> DiaEnumerator; 130cffff26bSZachary Turner if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator)) 131cffff26bSZachary Turner return nullptr; 132cffff26bSZachary Turner 133be6d1e49SZachary Turner return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator); 134cffff26bSZachary Turner } 135