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