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" 16*71f308adSChandler Carruth #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 17*71f308adSChandler 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 26cffff26bSZachary Turner DIASession *DIASession::createFromPdb(StringRef Path) { 27cffff26bSZachary Turner CComPtr<IDiaDataSource> DataSource; 28cffff26bSZachary Turner CComPtr<IDiaSession> Session; 29cffff26bSZachary Turner 30cffff26bSZachary Turner // We assume that CoInitializeEx has already been called by the executable. 31cffff26bSZachary Turner HRESULT Result = ::CoCreateInstance(CLSID_DiaSource, nullptr, 32cffff26bSZachary Turner CLSCTX_INPROC_SERVER, IID_IDiaDataSource, 33cffff26bSZachary Turner reinterpret_cast<LPVOID *>(&DataSource)); 34cffff26bSZachary Turner if (FAILED(Result)) 35cffff26bSZachary Turner return nullptr; 36cffff26bSZachary Turner 37cffff26bSZachary Turner llvm::SmallVector<UTF16, 128> Path16; 38cffff26bSZachary Turner if (!llvm::convertUTF8ToUTF16String(Path, Path16)) 39cffff26bSZachary Turner return nullptr; 40cffff26bSZachary Turner 41cffff26bSZachary Turner const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data()); 42cffff26bSZachary Turner if (FAILED(DataSource->loadDataFromPdb(Path16Str))) 43cffff26bSZachary Turner return nullptr; 44cffff26bSZachary Turner 45cffff26bSZachary Turner if (FAILED(DataSource->openSession(&Session))) 46cffff26bSZachary Turner return nullptr; 47cffff26bSZachary Turner return new DIASession(Session); 48cffff26bSZachary Turner } 49cffff26bSZachary Turner 50cffff26bSZachary Turner uint64_t DIASession::getLoadAddress() const { 51cffff26bSZachary Turner uint64_t LoadAddress; 52cffff26bSZachary Turner bool success = (S_OK == Session->get_loadAddress(&LoadAddress)); 53cffff26bSZachary Turner return (success) ? LoadAddress : 0; 54cffff26bSZachary Turner } 55cffff26bSZachary Turner 56cffff26bSZachary Turner void DIASession::setLoadAddress(uint64_t Address) { 57cffff26bSZachary Turner Session->put_loadAddress(Address); 58cffff26bSZachary Turner } 59cffff26bSZachary Turner 60cffff26bSZachary Turner std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const { 61cffff26bSZachary Turner CComPtr<IDiaSymbol> GlobalScope; 62cffff26bSZachary Turner if (S_OK != Session->get_globalScope(&GlobalScope)) 63cffff26bSZachary Turner return nullptr; 64cffff26bSZachary Turner 65be6d1e49SZachary Turner auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope); 66cffff26bSZachary Turner auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); 67cffff26bSZachary Turner std::unique_ptr<PDBSymbolExe> ExeSymbol( 68cffff26bSZachary Turner static_cast<PDBSymbolExe *>(PdbSymbol.release())); 69cffff26bSZachary Turner return ExeSymbol; 70cffff26bSZachary Turner } 71cffff26bSZachary Turner 72cffff26bSZachary Turner std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const { 73cffff26bSZachary Turner CComPtr<IDiaSymbol> LocatedSymbol; 74cffff26bSZachary Turner if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol)) 75cffff26bSZachary Turner return nullptr; 76cffff26bSZachary Turner 77be6d1e49SZachary Turner auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol); 78cffff26bSZachary Turner return PDBSymbol::create(*this, std::move(RawSymbol)); 79cffff26bSZachary Turner } 80cffff26bSZachary Turner 81a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const { 82a5549178SZachary Turner CComPtr<IDiaEnumSourceFiles> Files; 83a5549178SZachary Turner if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) 84a5549178SZachary Turner return nullptr; 85a5549178SZachary Turner 86be6d1e49SZachary Turner return llvm::make_unique<DIAEnumSourceFiles>(*this, Files); 87a5549178SZachary Turner } 88a5549178SZachary Turner 89a5549178SZachary Turner std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland( 90a5549178SZachary Turner const PDBSymbolCompiland &Compiland) const { 91a5549178SZachary Turner CComPtr<IDiaEnumSourceFiles> Files; 92a5549178SZachary Turner 93a5549178SZachary Turner const DIARawSymbol &RawSymbol = 94a5549178SZachary Turner static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); 95a5549178SZachary Turner if (S_OK != 96a5549178SZachary Turner Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files)) 97a5549178SZachary Turner return nullptr; 98a5549178SZachary Turner 99be6d1e49SZachary Turner return llvm::make_unique<DIAEnumSourceFiles>(*this, Files); 100a5549178SZachary Turner } 101a5549178SZachary Turner 102cffff26bSZachary Turner std::unique_ptr<IPDBSourceFile> 103cffff26bSZachary Turner DIASession::getSourceFileById(uint32_t FileId) const { 104cffff26bSZachary Turner CComPtr<IDiaSourceFile> LocatedFile; 105cffff26bSZachary Turner if (S_OK != Session->findFileById(FileId, &LocatedFile)) 106cffff26bSZachary Turner return nullptr; 107cffff26bSZachary Turner 108be6d1e49SZachary Turner return llvm::make_unique<DIASourceFile>(*this, LocatedFile); 109cffff26bSZachary Turner } 110cffff26bSZachary Turner 111cffff26bSZachary Turner std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const { 112cffff26bSZachary Turner CComPtr<IDiaEnumDebugStreams> DiaEnumerator; 113cffff26bSZachary Turner if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator)) 114cffff26bSZachary Turner return nullptr; 115cffff26bSZachary Turner 116be6d1e49SZachary Turner return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator); 117cffff26bSZachary Turner } 118