//===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h" #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" #include "llvm/DebugInfo/PDB/DIA/DIASession.h" #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/Support/ConvertUTF.h" using namespace llvm; namespace {} DIASession::DIASession(CComPtr DiaSession) : Session(DiaSession) {} DIASession *DIASession::createFromPdb(StringRef Path) { CComPtr DataSource; CComPtr Session; // We assume that CoInitializeEx has already been called by the executable. HRESULT Result = ::CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource, reinterpret_cast(&DataSource)); if (FAILED(Result)) return nullptr; llvm::SmallVector Path16; if (!llvm::convertUTF8ToUTF16String(Path, Path16)) return nullptr; const wchar_t *Path16Str = reinterpret_cast(Path16.data()); if (FAILED(DataSource->loadDataFromPdb(Path16Str))) return nullptr; if (FAILED(DataSource->openSession(&Session))) return nullptr; return new DIASession(Session); } uint64_t DIASession::getLoadAddress() const { uint64_t LoadAddress; bool success = (S_OK == Session->get_loadAddress(&LoadAddress)); return (success) ? LoadAddress : 0; } void DIASession::setLoadAddress(uint64_t Address) { Session->put_loadAddress(Address); } std::unique_ptr DIASession::getGlobalScope() const { CComPtr GlobalScope; if (S_OK != Session->get_globalScope(&GlobalScope)) return nullptr; auto RawSymbol = llvm::make_unique(*this, GlobalScope); auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); std::unique_ptr ExeSymbol( static_cast(PdbSymbol.release())); return ExeSymbol; } std::unique_ptr DIASession::getSymbolById(uint32_t SymbolId) const { CComPtr LocatedSymbol; if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol)) return nullptr; auto RawSymbol = llvm::make_unique(*this, LocatedSymbol); return PDBSymbol::create(*this, std::move(RawSymbol)); } std::unique_ptr DIASession::getAllSourceFiles() const { CComPtr Files; if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) return nullptr; return llvm::make_unique(*this, Files); } std::unique_ptr DIASession::getSourceFilesForCompiland( const PDBSymbolCompiland &Compiland) const { CComPtr Files; const DIARawSymbol &RawSymbol = static_cast(Compiland.getRawSymbol()); if (S_OK != Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files)) return nullptr; return llvm::make_unique(*this, Files); } std::unique_ptr DIASession::getSourceFileById(uint32_t FileId) const { CComPtr LocatedFile; if (S_OK != Session->findFileById(FileId, &LocatedFile)) return nullptr; return llvm::make_unique(*this, LocatedFile); } std::unique_ptr DIASession::getDebugStreams() const { CComPtr DiaEnumerator; if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator)) return nullptr; return llvm::make_unique(DiaEnumerator); }