DIASession.cpp revision 360784
1174604Sscottl//===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===// 2174604Sscottl// 3174604Sscottl// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4174604Sscottl// See https://llvm.org/LICENSE.txt for license information. 5174604Sscottl// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6174604Sscottl// 7174604Sscottl//===----------------------------------------------------------------------===// 8174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIASession.h" 9174604Sscottl#include "llvm/ADT/STLExtras.h" 10174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" 11174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h" 12174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h" 13174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h" 14174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h" 15174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h" 16174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAEnumTables.h" 17174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIAError.h" 18174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" 19174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h" 20174604Sscottl#include "llvm/DebugInfo/PDB/DIA/DIASupport.h" 21174604Sscottl#include "llvm/DebugInfo/PDB/GenericError.h" 22174604Sscottl#include "llvm/DebugInfo/PDB/PDB.h" 23174604Sscottl#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 24174604Sscottl#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 25174604Sscottl#include "llvm/Support/ConvertUTF.h" 26174604Sscottl#include "llvm/Support/Format.h" 27174604Sscottl#include "llvm/Support/FormatVariadic.h" 28174604Sscottl#include "llvm/Support/raw_ostream.h" 29174604Sscottl 30174604Sscottlusing namespace llvm; 31174604Sscottlusing namespace llvm::pdb; 32174604Sscottl 33174604Sscottltemplate <typename... Ts> 34174604Sscottlstatic Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args) { 35174604Sscottl SmallString<64> MessageStorage; 36174604Sscottl StringRef Context; 37174604Sscottl if (sizeof...(Args) > 0) { 38174604Sscottl MessageStorage = formatv(Str, std::forward<Ts>(Args)...).str(); 39174604Sscottl Context = MessageStorage; 40174604Sscottl } else 41174604Sscottl Context = Str; 42174604Sscottl 43174604Sscottl switch (Result) { 44174604Sscottl case E_PDB_NOT_FOUND: 45174604Sscottl return errorCodeToError(std::error_code(ENOENT, std::generic_category())); 46174604Sscottl case E_PDB_FORMAT: 47174604Sscottl return make_error<DIAError>(dia_error_code::invalid_file_format, Context); 48174604Sscottl case E_INVALIDARG: 49174604Sscottl return make_error<DIAError>(dia_error_code::invalid_parameter, Context); 50174604Sscottl case E_UNEXPECTED: 51174604Sscottl return make_error<DIAError>(dia_error_code::already_loaded, Context); 52174604Sscottl case E_PDB_INVALID_SIG: 53174604Sscottl case E_PDB_INVALID_AGE: 54174604Sscottl return make_error<DIAError>(dia_error_code::debug_info_mismatch, Context); 55174604Sscottl default: { 56174604Sscottl std::string S; 57174604Sscottl raw_string_ostream OS(S); 58174604Sscottl OS << "HRESULT: " << format_hex(static_cast<DWORD>(Result), 10, true) 59174604Sscottl << ": " << Context; 60174604Sscottl return make_error<DIAError>(dia_error_code::unspecified, OS.str()); 61174604Sscottl } 62174604Sscottl } 63174604Sscottl} 64174604Sscottl 65174604Sscottlstatic Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) { 66174604Sscottl if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, 67174604Sscottl IID_IDiaDataSource, 68174604Sscottl reinterpret_cast<LPVOID *>(&DiaDataSource)))) 69174604Sscottl return Error::success(); 70174604Sscottl 71174604Sscottl// If the CoCreateInstance call above failed, msdia*.dll is not registered. 72174604Sscottl// Try loading the DLL corresponding to the #included DIA SDK. 73174604Sscottl#if !defined(_MSC_VER) 74174604Sscottl return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading); 75174604Sscottl#else 76174604Sscottl const wchar_t *msdia_dll = L"msdia140.dll"; 77174604Sscottl HRESULT HR; 78174604Sscottl if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource, 79174604Sscottl reinterpret_cast<LPVOID *>(&DiaDataSource)))) 80174604Sscottl return ErrorFromHResult(HR, "Calling NoRegCoCreate"); 81174604Sscottl return Error::success(); 82174604Sscottl#endif 83174604Sscottl} 84174604Sscottl 85174604SscottlDIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {} 86174604Sscottl 87174604SscottlError DIASession::createFromPdb(StringRef Path, 88174604Sscottl std::unique_ptr<IPDBSession> &Session) { 89174604Sscottl CComPtr<IDiaDataSource> DiaDataSource; 90174604Sscottl CComPtr<IDiaSession> DiaSession; 91174604Sscottl 92174604Sscottl // We assume that CoInitializeEx has already been called by the executable. 93174604Sscottl if (auto E = LoadDIA(DiaDataSource)) 94174604Sscottl return E; 95174604Sscottl 96174604Sscottl llvm::SmallVector<UTF16, 128> Path16; 97174604Sscottl if (!llvm::convertUTF8ToUTF16String(Path, Path16)) 98174604Sscottl return make_error<PDBError>(pdb_error_code::invalid_utf8_path, Path); 99174604Sscottl 100174604Sscottl const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data()); 101174604Sscottl HRESULT HR; 102176018Sscottl if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) { 103176018Sscottl return ErrorFromHResult(HR, "Calling loadDataFromPdb {0}", Path); 104174604Sscottl } 105176018Sscottl 106174604Sscottl if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) 107174604Sscottl return ErrorFromHResult(HR, "Calling openSession"); 108174604Sscottl 109174604Sscottl Session.reset(new DIASession(DiaSession)); 110174604Sscottl return Error::success(); 111174604Sscottl} 112174604Sscottl 113174604SscottlError DIASession::createFromExe(StringRef Path, 114174604Sscottl std::unique_ptr<IPDBSession> &Session) { 115174604Sscottl CComPtr<IDiaDataSource> DiaDataSource; 116174604Sscottl CComPtr<IDiaSession> DiaSession; 117174604Sscottl 118174604Sscottl // We assume that CoInitializeEx has already been called by the executable. 119174604Sscottl if (auto EC = LoadDIA(DiaDataSource)) 120174604Sscottl return EC; 121174604Sscottl 122174604Sscottl llvm::SmallVector<UTF16, 128> Path16; 123174604Sscottl if (!llvm::convertUTF8ToUTF16String(Path, Path16)) 124174604Sscottl return make_error<PDBError>(pdb_error_code::invalid_utf8_path, Path); 125174604Sscottl 126174604Sscottl const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data()); 127174604Sscottl HRESULT HR; 128174604Sscottl if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) 129174604Sscottl return ErrorFromHResult(HR, "Calling loadDataForExe"); 130174604Sscottl 131174604Sscottl if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) 132174604Sscottl return ErrorFromHResult(HR, "Calling openSession"); 133174604Sscottl 134174604Sscottl Session.reset(new DIASession(DiaSession)); 135174604Sscottl return Error::success(); 136174604Sscottl} 137174604Sscottl 138174604Sscottluint64_t DIASession::getLoadAddress() const { 139174604Sscottl uint64_t LoadAddress; 140174604Sscottl bool success = (S_OK == Session->get_loadAddress(&LoadAddress)); 141174604Sscottl return (success) ? LoadAddress : 0; 142174604Sscottl} 143174604Sscottl 144174604Sscottlbool DIASession::setLoadAddress(uint64_t Address) { 145174604Sscottl return (S_OK == Session->put_loadAddress(Address)); 146174604Sscottl} 147174604Sscottl 148174604Sscottlstd::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() { 149174604Sscottl CComPtr<IDiaSymbol> GlobalScope; 150174604Sscottl if (S_OK != Session->get_globalScope(&GlobalScope)) 151174604Sscottl return nullptr; 152174604Sscottl 153174604Sscottl auto RawSymbol = std::make_unique<DIARawSymbol>(*this, GlobalScope); 154174604Sscottl auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); 155174604Sscottl std::unique_ptr<PDBSymbolExe> ExeSymbol( 156174604Sscottl static_cast<PDBSymbolExe *>(PdbSymbol.release())); 157174604Sscottl return ExeSymbol; 158174604Sscottl} 159174604Sscottl 160174604Sscottlbool DIASession::addressForVA(uint64_t VA, uint32_t &Section, 161174604Sscottl uint32_t &Offset) const { 162174604Sscottl DWORD ArgSection, ArgOffset = 0; 163174604Sscottl if (S_OK == Session->addressForVA(VA, &ArgSection, &ArgOffset)) { 164174604Sscottl Section = static_cast<uint32_t>(ArgSection); 165174604Sscottl Offset = static_cast<uint32_t>(ArgOffset); 166174604Sscottl return true; 167174604Sscottl } 168176018Sscottl return false; 169174604Sscottl} 170176018Sscottl 171174604Sscottlbool DIASession::addressForRVA(uint32_t RVA, uint32_t &Section, 172174604Sscottl uint32_t &Offset) const { 173174604Sscottl DWORD ArgSection, ArgOffset = 0; 174174604Sscottl if (S_OK == Session->addressForRVA(RVA, &ArgSection, &ArgOffset)) { 175174604Sscottl Section = static_cast<uint32_t>(ArgSection); 176174604Sscottl Offset = static_cast<uint32_t>(ArgOffset); 177174604Sscottl return true; 178174604Sscottl } 179174604Sscottl return false; 180174604Sscottl} 181174604Sscottl 182174604Sscottlstd::unique_ptr<PDBSymbol> 183174604SscottlDIASession::getSymbolById(SymIndexId SymbolId) const { 184174604Sscottl CComPtr<IDiaSymbol> LocatedSymbol; 185174604Sscottl if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol)) 186174604Sscottl return nullptr; 187174604Sscottl 188174604Sscottl auto RawSymbol = std::make_unique<DIARawSymbol>(*this, LocatedSymbol); 189174604Sscottl return PDBSymbol::create(*this, std::move(RawSymbol)); 190174604Sscottl} 191174604Sscottl 192174604Sscottlstd::unique_ptr<PDBSymbol> 193174604SscottlDIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const { 194174604Sscottl enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); 195174604Sscottl 196174604Sscottl CComPtr<IDiaSymbol> Symbol; 197174604Sscottl if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) { 198174604Sscottl ULONGLONG LoadAddr = 0; 199174604Sscottl if (S_OK != Session->get_loadAddress(&LoadAddr)) 200174604Sscottl return nullptr; 201174604Sscottl DWORD RVA = static_cast<DWORD>(Address - LoadAddr); 202174604Sscottl if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol)) 203174604Sscottl return nullptr; 204174604Sscottl } 205174604Sscottl auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol); 206174604Sscottl return PDBSymbol::create(*this, std::move(RawSymbol)); 207174604Sscottl} 208174604Sscottl 209174604Sscottlstd::unique_ptr<PDBSymbol> DIASession::findSymbolByRVA(uint32_t RVA, 210174604Sscottl PDB_SymType Type) const { 211174604Sscottl enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); 212174604Sscottl 213174604Sscottl CComPtr<IDiaSymbol> Symbol; 214174604Sscottl if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol)) 215174604Sscottl return nullptr; 216174604Sscottl 217174604Sscottl auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol); 218174604Sscottl return PDBSymbol::create(*this, std::move(RawSymbol)); 219174604Sscottl} 220174604Sscottl 221174604Sscottlstd::unique_ptr<PDBSymbol> 222174604SscottlDIASession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, 223174604Sscottl PDB_SymType Type) const { 224174604Sscottl enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); 225174604Sscottl 226174604Sscottl CComPtr<IDiaSymbol> Symbol; 227174604Sscottl if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol)) 228174604Sscottl return nullptr; 229174604Sscottl 230174604Sscottl auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol); 231174604Sscottl return PDBSymbol::create(*this, std::move(RawSymbol)); 232174604Sscottl} 233174604Sscottl 234174604Sscottlstd::unique_ptr<IPDBEnumLineNumbers> 235174604SscottlDIASession::findLineNumbers(const PDBSymbolCompiland &Compiland, 236174604Sscottl const IPDBSourceFile &File) const { 237174604Sscottl const DIARawSymbol &RawCompiland = 238174604Sscottl static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); 239174604Sscottl const DIASourceFile &RawFile = static_cast<const DIASourceFile &>(File); 240174604Sscottl 241174604Sscottl CComPtr<IDiaEnumLineNumbers> LineNumbers; 242174604Sscottl if (S_OK != Session->findLines(RawCompiland.getDiaSymbol(), 243174604Sscottl RawFile.getDiaFile(), &LineNumbers)) 244174604Sscottl return nullptr; 245174604Sscottl 246174604Sscottl return std::make_unique<DIAEnumLineNumbers>(LineNumbers); 247174604Sscottl} 248174604Sscottl 249174604Sscottlstd::unique_ptr<IPDBEnumLineNumbers> 250174604SscottlDIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const { 251174604Sscottl CComPtr<IDiaEnumLineNumbers> LineNumbers; 252174604Sscottl if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers)) { 253174604Sscottl ULONGLONG LoadAddr = 0; 254174604Sscottl if (S_OK != Session->get_loadAddress(&LoadAddr)) 255174604Sscottl return nullptr; 256174604Sscottl DWORD RVA = static_cast<DWORD>(Address - LoadAddr); 257174604Sscottl if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers)) 258174604Sscottl return nullptr; 259174604Sscottl } 260174604Sscottl return std::make_unique<DIAEnumLineNumbers>(LineNumbers); 261174604Sscottl} 262174604Sscottl 263174604Sscottlstd::unique_ptr<IPDBEnumLineNumbers> 264174604SscottlDIASession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const { 265174604Sscottl CComPtr<IDiaEnumLineNumbers> LineNumbers; 266174604Sscottl if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers)) 267174604Sscottl return nullptr; 268174604Sscottl 269174604Sscottl return std::make_unique<DIAEnumLineNumbers>(LineNumbers); 270174604Sscottl} 271174604Sscottl 272174604Sscottlstd::unique_ptr<IPDBEnumLineNumbers> 273174604SscottlDIASession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, 274174604Sscottl uint32_t Length) const { 275174604Sscottl CComPtr<IDiaEnumLineNumbers> LineNumbers; 276174604Sscottl if (S_OK != Session->findLinesByAddr(Section, Offset, Length, &LineNumbers)) 277174604Sscottl return nullptr; 278174604Sscottl 279174604Sscottl return std::make_unique<DIAEnumLineNumbers>(LineNumbers); 280174604Sscottl} 281174604Sscottl 282174604Sscottlstd::unique_ptr<IPDBEnumSourceFiles> 283176018SscottlDIASession::findSourceFiles(const PDBSymbolCompiland *Compiland, 284174604Sscottl llvm::StringRef Pattern, 285174604Sscottl PDB_NameSearchFlags Flags) const { 286174604Sscottl IDiaSymbol *DiaCompiland = nullptr; 287174604Sscottl CComBSTR Utf16Pattern; 288174604Sscottl if (!Pattern.empty()) 289174604Sscottl Utf16Pattern = CComBSTR(Pattern.data()); 290174604Sscottl 291174604Sscottl if (Compiland) 292174604Sscottl DiaCompiland = static_cast<const DIARawSymbol &>(Compiland->getRawSymbol()) 293174604Sscottl .getDiaSymbol(); 294174604Sscottl 295174604Sscottl Flags = static_cast<PDB_NameSearchFlags>( 296174604Sscottl Flags | PDB_NameSearchFlags::NS_FileNameExtMatch); 297174604Sscottl CComPtr<IDiaEnumSourceFiles> SourceFiles; 298174604Sscottl if (S_OK != 299174604Sscottl Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles)) 300174604Sscottl return nullptr; 301174604Sscottl return std::make_unique<DIAEnumSourceFiles>(*this, SourceFiles); 302174604Sscottl} 303174604Sscottl 304174604Sscottlstd::unique_ptr<IPDBSourceFile> 305174604SscottlDIASession::findOneSourceFile(const PDBSymbolCompiland *Compiland, 306174604Sscottl llvm::StringRef Pattern, 307174604Sscottl PDB_NameSearchFlags Flags) const { 308174604Sscottl auto SourceFiles = findSourceFiles(Compiland, Pattern, Flags); 309174604Sscottl if (!SourceFiles || SourceFiles->getChildCount() == 0) 310174604Sscottl return nullptr; 311174604Sscottl return SourceFiles->getNext(); 312174604Sscottl} 313174604Sscottl 314174604Sscottlstd::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>> 315176018SscottlDIASession::findCompilandsForSourceFile(llvm::StringRef Pattern, 316176018Sscottl PDB_NameSearchFlags Flags) const { 317176018Sscottl auto File = findOneSourceFile(nullptr, Pattern, Flags); 318176018Sscottl if (!File) 319176018Sscottl return nullptr; 320176018Sscottl return File->getCompilands(); 321176018Sscottl} 322176018Sscottl 323176018Sscottlstd::unique_ptr<PDBSymbolCompiland> 324174604SscottlDIASession::findOneCompilandForSourceFile(llvm::StringRef Pattern, 325174604Sscottl PDB_NameSearchFlags Flags) const { 326174604Sscottl auto Compilands = findCompilandsForSourceFile(Pattern, Flags); 327174604Sscottl if (!Compilands || Compilands->getChildCount() == 0) 328174604Sscottl return nullptr; 329174604Sscottl return Compilands->getNext(); 330174604Sscottl} 331174604Sscottl 332174604Sscottlstd::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const { 333174604Sscottl CComPtr<IDiaEnumSourceFiles> Files; 334174604Sscottl if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) 335174604Sscottl return nullptr; 336174604Sscottl 337174604Sscottl return std::make_unique<DIAEnumSourceFiles>(*this, Files); 338174604Sscottl} 339174604Sscottl 340174604Sscottlstd::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland( 341174604Sscottl const PDBSymbolCompiland &Compiland) const { 342174604Sscottl CComPtr<IDiaEnumSourceFiles> Files; 343174604Sscottl 344174604Sscottl const DIARawSymbol &RawSymbol = 345174604Sscottl static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); 346174604Sscottl if (S_OK != 347174604Sscottl Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files)) 348174604Sscottl return nullptr; 349174604Sscottl 350174604Sscottl return std::make_unique<DIAEnumSourceFiles>(*this, Files); 351174604Sscottl} 352174604Sscottl 353176018Sscottlstd::unique_ptr<IPDBSourceFile> 354176018SscottlDIASession::getSourceFileById(uint32_t FileId) const { 355174604Sscottl CComPtr<IDiaSourceFile> LocatedFile; 356174604Sscottl if (S_OK != Session->findFileById(FileId, &LocatedFile)) 357174604Sscottl return nullptr; 358174604Sscottl 359174604Sscottl return std::make_unique<DIASourceFile>(*this, LocatedFile); 360174604Sscottl} 361174604Sscottl 362174604Sscottlstd::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const { 363174604Sscottl CComPtr<IDiaEnumDebugStreams> DiaEnumerator; 364176018Sscottl if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator)) 365176018Sscottl return nullptr; 366174604Sscottl 367174604Sscottl return std::make_unique<DIAEnumDebugStreams>(DiaEnumerator); 368174604Sscottl} 369174604Sscottl 370174604Sscottlstd::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const { 371174604Sscottl CComPtr<IDiaEnumTables> DiaEnumerator; 372174604Sscottl if (S_OK != Session->getEnumTables(&DiaEnumerator)) 373174604Sscottl return nullptr; 374174604Sscottl 375174604Sscottl return std::make_unique<DIAEnumTables>(DiaEnumerator); 376174604Sscottl} 377174604Sscottl 378174604Sscottltemplate <class T> static CComPtr<T> getTableEnumerator(IDiaSession &Session) { 379174604Sscottl CComPtr<T> Enumerator; 380174604Sscottl CComPtr<IDiaEnumTables> ET; 381174604Sscottl CComPtr<IDiaTable> Table; 382174604Sscottl ULONG Count = 0; 383174604Sscottl 384174604Sscottl if (Session.getEnumTables(&ET) != S_OK) 385174604Sscottl return nullptr; 386174604Sscottl 387174604Sscottl while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) { 388174604Sscottl // There is only one table that matches the given iid 389174604Sscottl if (S_OK == Table->QueryInterface(__uuidof(T), (void **)&Enumerator)) 390174604Sscottl break; 391174604Sscottl Table.Release(); 392174604Sscottl } 393174604Sscottl return Enumerator; 394174604Sscottl} 395174604Sscottlstd::unique_ptr<IPDBEnumInjectedSources> 396174604SscottlDIASession::getInjectedSources() const { 397174604Sscottl CComPtr<IDiaEnumInjectedSources> Files = 398174604Sscottl getTableEnumerator<IDiaEnumInjectedSources>(*Session); 399174604Sscottl if (!Files) 400174604Sscottl return nullptr; 401174604Sscottl 402174604Sscottl return std::make_unique<DIAEnumInjectedSources>(Files); 403174604Sscottl} 404174604Sscottl 405174604Sscottlstd::unique_ptr<IPDBEnumSectionContribs> 406174604SscottlDIASession::getSectionContribs() const { 407174604Sscottl CComPtr<IDiaEnumSectionContribs> Sections = 408174604Sscottl getTableEnumerator<IDiaEnumSectionContribs>(*Session); 409174604Sscottl if (!Sections) 410174604Sscottl return nullptr; 411174604Sscottl 412174604Sscottl return std::make_unique<DIAEnumSectionContribs>(*this, Sections); 413174604Sscottl} 414174604Sscottl 415174604Sscottlstd::unique_ptr<IPDBEnumFrameData> 416174604SscottlDIASession::getFrameData() const { 417174604Sscottl CComPtr<IDiaEnumFrameData> FD = 418174604Sscottl getTableEnumerator<IDiaEnumFrameData>(*Session); 419174604Sscottl if (!FD) 420174604Sscottl return nullptr; 421174604Sscottl 422174604Sscottl return std::make_unique<DIAEnumFrameData>(FD); 423174604Sscottl} 424174604Sscottl