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