• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DIASession(CComPtr<IDiaSession> DiaSession)24 DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
25 
createFromPdb(StringRef Path,std::unique_ptr<IPDBSession> & Session)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 
getLoadAddress() const67 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 
setLoadAddress(uint64_t Address)73 void DIASession::setLoadAddress(uint64_t Address) {
74   Session->put_loadAddress(Address);
75 }
76 
getGlobalScope() const77 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 
getSymbolById(uint32_t SymbolId) const89 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 
getAllSourceFiles() const98 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 
getSourceFilesForCompiland(const PDBSymbolCompiland & Compiland) const106 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>
getSourceFileById(uint32_t FileId) const120 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 
getDebugStreams() const128 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