34 template <
typename... Ts>
38 if (
sizeof...(
Args) > 0) {
39 MessageStorage =
formatv(Str, std::forward<Ts>(
Args)...).str();
40 Context = MessageStorage;
53 case E_PDB_INVALID_SIG:
54 case E_PDB_INVALID_AGE:
59 OS <<
"HRESULT: " <<
format_hex(static_cast<DWORD>(Result), 10,
true)
67 if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource,
nullptr, CLSCTX_INPROC_SERVER,
69 reinterpret_cast<LPVOID *>(&DiaDataSource))))
74 #if !defined(_MSC_VER) 77 const wchar_t *msdia_dll =
nullptr;
78 #if _MSC_VER >= 1900 && _MSC_VER < 2000 79 msdia_dll = L
"msdia140.dll";
80 #elif _MSC_VER >= 1800 81 msdia_dll = L
"msdia120.dll";
83 #error "Unknown Visual Studio version." 87 if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
88 reinterpret_cast<LPVOID *>(&DiaDataSource))))
97 std::unique_ptr<IPDBSession> &Session) {
98 CComPtr<IDiaDataSource> DiaDataSource;
99 CComPtr<IDiaSession> DiaSession;
102 if (
auto E =
LoadDIA(DiaDataSource))
109 const wchar_t *Path16Str =
reinterpret_cast<const wchar_t *
>(Path16.
data());
111 if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {
115 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
123 std::unique_ptr<IPDBSession> &Session) {
124 CComPtr<IDiaDataSource> DiaDataSource;
125 CComPtr<IDiaSession> DiaSession;
128 if (
auto EC =
LoadDIA(DiaDataSource))
135 const wchar_t *Path16Str =
reinterpret_cast<const wchar_t *
>(Path16.
data());
137 if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str,
nullptr,
nullptr)))
140 if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
148 uint64_t LoadAddress;
149 bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
150 return (success) ? LoadAddress : 0;
154 return (S_OK == Session->put_loadAddress(Address));
158 CComPtr<IDiaSymbol> GlobalScope;
159 if (S_OK != Session->get_globalScope(&GlobalScope))
162 auto RawSymbol = llvm::make_unique<DIARawSymbol>(*
this, GlobalScope);
164 std::unique_ptr<PDBSymbolExe> ExeSymbol(
165 static_cast<PDBSymbolExe *>(PdbSymbol.release()));
171 DWORD ArgSection, ArgOffset = 0;
172 if (S_OK == Session->addressForVA(VA, &ArgSection, &ArgOffset)) {
173 Section =
static_cast<uint32_t>(ArgSection);
174 Offset =
static_cast<uint32_t>(ArgOffset);
182 DWORD ArgSection, ArgOffset = 0;
183 if (S_OK == Session->addressForRVA(RVA, &ArgSection, &ArgOffset)) {
184 Section =
static_cast<uint32_t>(ArgSection);
185 Offset =
static_cast<uint32_t>(ArgOffset);
191 std::unique_ptr<PDBSymbol>
193 CComPtr<IDiaSymbol> LocatedSymbol;
194 if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
197 auto RawSymbol = llvm::make_unique<DIARawSymbol>(*
this, LocatedSymbol);
201 std::unique_ptr<PDBSymbol>
203 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
205 CComPtr<IDiaSymbol>
Symbol;
206 if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) {
207 ULONGLONG LoadAddr = 0;
208 if (S_OK != Session->get_loadAddress(&LoadAddr))
210 DWORD RVA =
static_cast<DWORD>(Address - LoadAddr);
211 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
214 auto RawSymbol = llvm::make_unique<DIARawSymbol>(*
this,
Symbol);
220 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
222 CComPtr<IDiaSymbol>
Symbol;
223 if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
226 auto RawSymbol = llvm::make_unique<DIARawSymbol>(*
this,
Symbol);
230 std::unique_ptr<PDBSymbol>
233 enum SymTagEnum EnumVal =
static_cast<enum SymTagEnum
>(
Type);
235 CComPtr<IDiaSymbol>
Symbol;
236 if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol))
239 auto RawSymbol = llvm::make_unique<DIARawSymbol>(*
this,
Symbol);
243 std::unique_ptr<IPDBEnumLineNumbers>
251 if (S_OK != Session->findLines(RawCompiland.
getDiaSymbol(),
255 return llvm::make_unique<DIAEnumLineNumbers>(
LineNumbers);
258 std::unique_ptr<IPDBEnumLineNumbers>
261 if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers)) {
262 ULONGLONG LoadAddr = 0;
263 if (S_OK != Session->get_loadAddress(&LoadAddr))
265 DWORD RVA =
static_cast<DWORD>(Address - LoadAddr);
266 if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
269 return llvm::make_unique<DIAEnumLineNumbers>(
LineNumbers);
272 std::unique_ptr<IPDBEnumLineNumbers>
275 if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
278 return llvm::make_unique<DIAEnumLineNumbers>(
LineNumbers);
281 std::unique_ptr<IPDBEnumLineNumbers>
285 if (S_OK != Session->findLinesByAddr(Section, Offset, Length, &LineNumbers))
288 return llvm::make_unique<DIAEnumLineNumbers>(
LineNumbers);
291 std::unique_ptr<IPDBEnumSourceFiles>
295 IDiaSymbol *DiaCompiland =
nullptr;
296 CComBSTR Utf16Pattern;
297 if (!Pattern.
empty())
298 Utf16Pattern = CComBSTR(Pattern.
data());
308 Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles))
310 return llvm::make_unique<DIAEnumSourceFiles>(*
this,
SourceFiles);
313 std::unique_ptr<IPDBSourceFile>
323 std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
329 return File->getCompilands();
332 std::unique_ptr<PDBSymbolCompiland>
336 if (!Compilands || Compilands->getChildCount() == 0)
338 return Compilands->getNext();
342 CComPtr<IDiaEnumSourceFiles> Files;
343 if (S_OK != Session->findFile(
nullptr,
nullptr, nsNone, &Files))
346 return llvm::make_unique<DIAEnumSourceFiles>(*
this, Files);
351 CComPtr<IDiaEnumSourceFiles> Files;
356 Session->findFile(RawSymbol.
getDiaSymbol(),
nullptr, nsNone, &Files))
359 return llvm::make_unique<DIAEnumSourceFiles>(*
this, Files);
362 std::unique_ptr<IPDBSourceFile>
364 CComPtr<IDiaSourceFile> LocatedFile;
365 if (S_OK != Session->findFileById(FileId, &LocatedFile))
368 return llvm::make_unique<DIASourceFile>(*
this, LocatedFile);
372 CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
373 if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
376 return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
380 CComPtr<IDiaEnumTables> DiaEnumerator;
381 if (S_OK != Session->getEnumTables(&DiaEnumerator))
384 return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
389 CComPtr<IDiaEnumTables> ET;
390 CComPtr<IDiaTable> Table;
393 if (Session.getEnumTables(&ET) != S_OK)
396 while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) {
398 if (S_OK == Table->QueryInterface(__uuidof(
T), (
void **)&Enumerator))
404 std::unique_ptr<IPDBEnumInjectedSources>
406 CComPtr<IDiaEnumInjectedSources> Files =
407 getTableEnumerator<IDiaEnumInjectedSources>(*Session);
411 return llvm::make_unique<DIAEnumInjectedSources>(Files);
414 std::unique_ptr<IPDBEnumSectionContribs>
416 CComPtr<IDiaEnumSectionContribs> Sections =
417 getTableEnumerator<IDiaEnumSectionContribs>(*Session);
421 return llvm::make_unique<DIAEnumSectionContribs>(*
this, Sections);
424 std::unique_ptr<IPDBEnumFrameData>
426 CComPtr<IDiaEnumFrameData> FD =
427 getTableEnumerator<IDiaEnumFrameData>(*Session);
431 return llvm::make_unique<DIAEnumFrameData>(FD);
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override
This class represents lattice values for constants.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
std::unique_ptr< PDBSymbolExe > getGlobalScope() override
PDB_NameSearchFlags
Defines flags used for enumerating child symbols.
std::unique_ptr< IPDBEnumInjectedSources > getInjectedSources() const override
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::unique_ptr< PDBSymbol > findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override
std::unique_ptr< IPDBEnumChildren< PDBSymbolCompiland > > findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
IPDBSourceFile defines an interface used to represent source files whose information are stored in th...
std::unique_ptr< IPDBSourceFile > getSourceFileById(uint32_t FileId) const override
bool setLoadAddress(uint64_t Address) override
std::unique_ptr< PDBSymbol > getSymbolById(SymIndexId SymbolId) const override
std::unique_ptr< IPDBEnumSourceFiles > findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
static Error createFromPdb(StringRef Path, std::unique_ptr< IPDBSession > &Session)
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, uint32_t Length) const override
std::unique_ptr< IPDBEnumFrameData > getFrameData() const override
std::unique_ptr< IPDBSourceFile > findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override
bool convertUTF8ToUTF16String(StringRef SrcUTF8, SmallVectorImpl< UTF16 > &DstUTF16)
Converts a UTF-8 string into a UTF-16 string with native endianness.
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx.
std::unique_ptr< PDBSymbol > findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const override
std::unique_ptr< IPDBEnumSourceFiles > getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const override
The instances of the Type class are immutable: once they are created, they are never changed...
std::unique_ptr< IPDBEnumSourceFiles > getAllSourceFiles() const override
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args)
DIASession(CComPtr< IDiaSession > DiaSession)
std::unique_ptr< IPDBEnumLineNumbers > findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
bool addressForRVA(uint32_t RVA, uint32_t &Section, uint32_t &Offset) const override
std::unique_ptr< IPDBEnumDataStreams > getDebugStreams() const override
static ErrorSuccess success()
Create a success value.
std::unique_ptr< PDBSymbolCompiland > findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const override
static Error LoadDIA(CComPtr< IDiaDataSource > &DiaDataSource)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::unique_ptr< PDBSymbol > findSymbolBySectOffset(uint32_t Section, uint32_t Offset, PDB_SymType Type) const override
const IPDBRawSymbol & getRawSymbol() const
CComPtr< IDiaSourceFile > getDiaFile() const
std::unique_ptr< IPDBEnumSectionContribs > getSectionContribs() const override
success
Parameters (see the expansion example below): (the builder, addr, loaded, new_val, ordering, /* OUT.
static CComPtr< T > getTableEnumerator(IDiaSession &Session)
pointer data()
Return a pointer to the vector's buffer, even if empty().
std::unique_ptr< IPDBEnumTables > getEnumTables() const override
CComPtr< IDiaSymbol > getDiaSymbol() const
static Error createFromExe(StringRef Path, std::unique_ptr< IPDBSession > &Session)
A raw_ostream that writes to an std::string.
Lightweight error class with error context and mandatory checking.
bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override
static std::unique_ptr< PDBSymbol > create(const IPDBSession &PDBSession, std::unique_ptr< IPDBRawSymbol > RawSymbol)
StringRef - Represent a constant reference to a string, i.e.
uint64_t getLoadAddress() const override
constexpr char Args[]
Key for Kernel::Metadata::mArgs.