33template <
typename... Ts>
37 if (
sizeof...(Args) > 0) {
38 MessageStorage =
formatv(Str, std::forward<Ts>(Args)...).str();
39 Context = MessageStorage;
47 return make_error<DIAError>(dia_error_code::invalid_file_format, Context);
49 return make_error<DIAError>(dia_error_code::invalid_parameter, Context);
51 return make_error<DIAError>(dia_error_code::already_loaded, Context);
52 case E_PDB_INVALID_SIG:
53 case E_PDB_INVALID_AGE:
54 return make_error<DIAError>(dia_error_code::debug_info_mismatch, Context);
58 OS <<
"HRESULT: " <<
format_hex(
static_cast<DWORD
>(Result), 10,
true)
60 return make_error<DIAError>(dia_error_code::unspecified,
OS.str());
66 if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource,
nullptr, CLSCTX_INPROC_SERVER,
68 reinterpret_cast<LPVOID *
>(&DiaDataSource))))
74 return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading);
76 const wchar_t *msdia_dll = L
"msdia140.dll";
78 if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
79 reinterpret_cast<LPVOID *
>(&DiaDataSource))))
88 std::unique_ptr<IPDBSession> &Session) {
89 CComPtr<IDiaDataSource> DiaDataSource;
90 CComPtr<IDiaSession> DiaSession;
93 if (
auto E =
LoadDIA(DiaDataSource))
100 const wchar_t *Path16Str =
reinterpret_cast<const wchar_t *
>(Path16.
data());
102 if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {
106 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
114 std::unique_ptr<IPDBSession> &Session) {
115 CComPtr<IDiaDataSource> DiaDataSource;
116 CComPtr<IDiaSession> DiaSession;
119 if (
auto EC =
LoadDIA(DiaDataSource))
126 const wchar_t *Path16Str =
reinterpret_cast<const wchar_t *
>(Path16.
data());
128 if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str,
nullptr,
nullptr)))
131 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
140 bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
141 return (
success) ? LoadAddress : 0;
145 return (S_OK == Session->put_loadAddress(
Address));
149 CComPtr<IDiaSymbol> GlobalScope;
150 if (S_OK != Session->get_globalScope(&GlobalScope))
153 auto RawSymbol = std::make_unique<DIARawSymbol>(*
this, GlobalScope);
155 std::unique_ptr<PDBSymbolExe> ExeSymbol(
162 DWORD ArgSection, ArgOffset = 0;
163 if (S_OK == Session->addressForVA(VA, &ArgSection, &ArgOffset)) {
164 Section =
static_cast<uint32_t>(ArgSection);
173 DWORD ArgSection, ArgOffset = 0;
174 if (S_OK == Session->addressForRVA(RVA, &ArgSection, &ArgOffset)) {
175 Section =
static_cast<uint32_t>(ArgSection);
182std::unique_ptr<PDBSymbol>
184 CComPtr<IDiaSymbol> LocatedSymbol;
185 if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
188 auto RawSymbol = std::make_unique<DIARawSymbol>(*
this, LocatedSymbol);
194 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
196 CComPtr<IDiaSymbol> Symbol;
197 if (S_OK != Session->findSymbolByVA(
Address, EnumVal, &Symbol)) {
198 ULONGLONG LoadAddr = 0;
199 if (S_OK != Session->get_loadAddress(&LoadAddr))
201 DWORD RVA =
static_cast<DWORD
>(
Address - LoadAddr);
202 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
205 auto RawSymbol = std::make_unique<DIARawSymbol>(*
this, Symbol);
211 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
213 CComPtr<IDiaSymbol> Symbol;
214 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
217 auto RawSymbol = std::make_unique<DIARawSymbol>(*
this, Symbol);
221std::unique_ptr<PDBSymbol>
224 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
226 CComPtr<IDiaSymbol> Symbol;
227 if (S_OK != Session->findSymbolByAddr(Sect,
Offset, EnumVal, &Symbol))
230 auto RawSymbol = std::make_unique<DIARawSymbol>(*
this, Symbol);
234std::unique_ptr<IPDBEnumLineNumbers>
242 if (S_OK != Session->findLines(RawCompiland.
getDiaSymbol(),
246 return std::make_unique<DIAEnumLineNumbers>(
LineNumbers);
249std::unique_ptr<IPDBEnumLineNumbers>
253 ULONGLONG LoadAddr = 0;
254 if (S_OK != Session->get_loadAddress(&LoadAddr))
256 DWORD RVA =
static_cast<DWORD
>(
Address - LoadAddr);
260 return std::make_unique<DIAEnumLineNumbers>(
LineNumbers);
263std::unique_ptr<IPDBEnumLineNumbers>
269 return std::make_unique<DIAEnumLineNumbers>(
LineNumbers);
272std::unique_ptr<IPDBEnumLineNumbers>
279 return std::make_unique<DIAEnumLineNumbers>(
LineNumbers);
282std::unique_ptr<IPDBEnumSourceFiles>
286 IDiaSymbol *DiaCompiland =
nullptr;
287 CComBSTR Utf16Pattern;
289 Utf16Pattern = CComBSTR(
Pattern.data());
299 Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &
SourceFiles))
301 return std::make_unique<DIAEnumSourceFiles>(*
this,
SourceFiles);
304std::unique_ptr<IPDBSourceFile>
314std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
320 return File->getCompilands();
323std::unique_ptr<PDBSymbolCompiland>
327 if (!Compilands || Compilands->getChildCount() == 0)
329 return Compilands->getNext();
333 CComPtr<IDiaEnumSourceFiles> Files;
334 if (S_OK != Session->findFile(
nullptr,
nullptr, nsNone, &Files))
337 return std::make_unique<DIAEnumSourceFiles>(*
this, Files);
342 CComPtr<IDiaEnumSourceFiles> Files;
347 Session->findFile(RawSymbol.
getDiaSymbol(),
nullptr, nsNone, &Files))
350 return std::make_unique<DIAEnumSourceFiles>(*
this, Files);
353std::unique_ptr<IPDBSourceFile>
355 CComPtr<IDiaSourceFile> LocatedFile;
356 if (S_OK != Session->findFileById(FileId, &LocatedFile))
359 return std::make_unique<DIASourceFile>(*
this, LocatedFile);
363 CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
364 if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
367 return std::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
371 CComPtr<IDiaEnumTables> DiaEnumerator;
372 if (S_OK != Session->getEnumTables(&DiaEnumerator))
375 return std::make_unique<DIAEnumTables>(DiaEnumerator);
380 CComPtr<IDiaEnumTables> ET;
381 CComPtr<IDiaTable> Table;
384 if (Session.getEnumTables(&ET) != S_OK)
387 while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) {
389 if (S_OK == Table->QueryInterface(__uuidof(
T), (
void **)&
Enumerator))
395std::unique_ptr<IPDBEnumInjectedSources>
397 CComPtr<IDiaEnumInjectedSources> Files =
398 getTableEnumerator<IDiaEnumInjectedSources>(*Session);
402 return std::make_unique<DIAEnumInjectedSources>(Files);
405std::unique_ptr<IPDBEnumSectionContribs>
407 CComPtr<IDiaEnumSectionContribs> Sections =
408 getTableEnumerator<IDiaEnumSectionContribs>(*Session);
412 return std::make_unique<DIAEnumSectionContribs>(*
this, Sections);
415std::unique_ptr<IPDBEnumFrameData>
417 CComPtr<IDiaEnumFrameData> FD =
418 getTableEnumerator<IDiaEnumFrameData>(*Session);
422 return std::make_unique<DIAEnumFrameData>(FD);
static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args)
static CComPtr< T > getTableEnumerator(IDiaSession &Session)
static Error LoadDIA(CComPtr< IDiaDataSource > &DiaDataSource)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
CComPtr< IDiaSymbol > getDiaSymbol() const
std::unique_ptr< IPDBSourceFile > findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
std::unique_ptr< IPDBEnumSourceFiles > findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override
std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override
static Error createFromExe(StringRef Path, std::unique_ptr< IPDBSession > &Session)
uint64_t getLoadAddress() const override
std::unique_ptr< IPDBEnumSourceFiles > getAllSourceFiles() const override
bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override
std::unique_ptr< PDBSymbolExe > getGlobalScope() override
std::unique_ptr< PDBSymbol > findSymbolByAddress(uint64_t Address, PDB_SymType Type) override
std::unique_ptr< IPDBEnumInjectedSources > getInjectedSources() const override
std::unique_ptr< PDBSymbolCompiland > findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
DIASession(CComPtr< IDiaSession > DiaSession)
std::unique_ptr< IPDBEnumChildren< PDBSymbolCompiland > > findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
bool setLoadAddress(uint64_t Address) override
static Error createFromPdb(StringRef Path, std::unique_ptr< IPDBSession > &Session)
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override
std::unique_ptr< IPDBEnumDataStreams > getDebugStreams() const override
bool addressForRVA(uint32_t RVA, uint32_t &Section, uint32_t &Offset) const override
std::unique_ptr< PDBSymbol > getSymbolById(SymIndexId SymbolId) const override
std::unique_ptr< IPDBSourceFile > getSourceFileById(uint32_t FileId) const override
std::unique_ptr< IPDBEnumFrameData > getFrameData() const override
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, uint32_t Length) const override
std::unique_ptr< PDBSymbol > findSymbolByRVA(uint32_t RVA, PDB_SymType Type) override
std::unique_ptr< IPDBEnumTables > getEnumTables() const override
std::unique_ptr< PDBSymbol > findSymbolBySectOffset(uint32_t Section, uint32_t Offset, PDB_SymType Type) override
std::unique_ptr< IPDBEnumSectionContribs > getSectionContribs() const override
CComPtr< IDiaSourceFile > getDiaFile() const
IPDBSourceFile defines an interface used to represent source files whose information are stored in th...
static std::unique_ptr< PDBSymbol > create(const IPDBSession &PDBSession, std::unique_ptr< IPDBRawSymbol > RawSymbol)
A raw_ostream that writes to an std::string.
PDB_NameSearchFlags
Defines flags used for enumerating child symbols.
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn....
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool convertUTF8ToUTF16String(StringRef SrcUTF8, SmallVectorImpl< UTF16 > &DstUTF16)
Converts a UTF-8 string into a UTF-16 string with native endianness.