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