blob: 3b5c951e2bac5d858b3e1dbd773c9cdc7bad08bb [file] [log] [blame]
Zachary Turnercffff262015-02-10 21:17:52 +00001//===- 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/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
11#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
12#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
13#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
14#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
15#include "llvm/Support/ConvertUTF.h"
16
17using namespace llvm;
18
19namespace {}
20
21DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
22
23DIASession *DIASession::createFromPdb(StringRef Path) {
24 CComPtr<IDiaDataSource> DataSource;
25 CComPtr<IDiaSession> Session;
26
27 // We assume that CoInitializeEx has already been called by the executable.
28 HRESULT Result = ::CoCreateInstance(CLSID_DiaSource, nullptr,
29 CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
30 reinterpret_cast<LPVOID *>(&DataSource));
31 if (FAILED(Result))
32 return nullptr;
33
34 llvm::SmallVector<UTF16, 128> Path16;
35 if (!llvm::convertUTF8ToUTF16String(Path, Path16))
36 return nullptr;
37
38 const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
39 if (FAILED(DataSource->loadDataFromPdb(Path16Str)))
40 return nullptr;
41
42 if (FAILED(DataSource->openSession(&Session)))
43 return nullptr;
44 return new DIASession(Session);
45}
46
47uint64_t DIASession::getLoadAddress() const {
48 uint64_t LoadAddress;
49 bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
50 return (success) ? LoadAddress : 0;
51}
52
53void DIASession::setLoadAddress(uint64_t Address) {
54 Session->put_loadAddress(Address);
55}
56
57std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
58 CComPtr<IDiaSymbol> GlobalScope;
59 if (S_OK != Session->get_globalScope(&GlobalScope))
60 return nullptr;
61
62 auto RawSymbol = std::make_unique<DIARawSymbol>(*this, GlobalScope);
63 auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
64 std::unique_ptr<PDBSymbolExe> ExeSymbol(
65 static_cast<PDBSymbolExe *>(PdbSymbol.release()));
66 return ExeSymbol;
67}
68
69std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
70 CComPtr<IDiaSymbol> LocatedSymbol;
71 if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
72 return nullptr;
73
74 auto RawSymbol = std::make_unique<DIARawSymbol>(*this, LocatedSymbol);
75 return PDBSymbol::create(*this, std::move(RawSymbol));
76}
77
78std::unique_ptr<IPDBSourceFile>
79DIASession::getSourceFileById(uint32_t FileId) const {
80 CComPtr<IDiaSourceFile> LocatedFile;
81 if (S_OK != Session->findFileById(FileId, &LocatedFile))
82 return nullptr;
83
84 return std::make_unique<DIASourceFile>(*this, LocatedFile);
85}
86
87std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
88 CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
89 if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
90 return nullptr;
91
92 return std::unique_ptr<IPDBEnumDataStreams>(
93 new DIAEnumDebugStreams(DiaEnumerator));
94}