diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp | 63 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/PDB.cpp | 13 |
2 files changed, 74 insertions, 2 deletions
diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp index 4966bea96f6..e3e3fc05ab3 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -9,6 +9,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h" #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" #include "llvm/DebugInfo/PDB/DIA/DIASession.h" @@ -64,6 +65,50 @@ PDB_ErrorCode DIASession::createFromPdb(StringRef Path, return PDB_ErrorCode::Success; } +PDB_ErrorCode DIASession::createFromExe(StringRef Path, + std::unique_ptr<IPDBSession> &Session) { + CComPtr<IDiaDataSource> DiaDataSource; + CComPtr<IDiaSession> DiaSession; + + // We assume that CoInitializeEx has already been called by the executable. + HRESULT Result = ::CoCreateInstance( + CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource, + reinterpret_cast<LPVOID *>(&DiaDataSource)); + if (FAILED(Result)) + return PDB_ErrorCode::NoPdbImpl; + + llvm::SmallVector<UTF16, 128> Path16; + if (!llvm::convertUTF8ToUTF16String(Path, Path16)) + return PDB_ErrorCode::InvalidPath; + + const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data()); + if (FAILED(Result = + DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) { + if (Result == E_PDB_NOT_FOUND) + return PDB_ErrorCode::InvalidPath; + else if (Result == E_PDB_FORMAT) + return PDB_ErrorCode::InvalidFileFormat; + else if (Result == E_PDB_INVALID_SIG || Result == E_PDB_INVALID_AGE) + return PDB_ErrorCode::DebugInfoMismatch; + else if (Result == E_INVALIDARG) + return PDB_ErrorCode::InvalidParameter; + else if (Result == E_UNEXPECTED) + return PDB_ErrorCode::AlreadyLoaded; + else + return PDB_ErrorCode::UnknownError; + } + + if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) { + if (Result == E_OUTOFMEMORY) + return PDB_ErrorCode::NoMemory; + else + return PDB_ErrorCode::UnknownError; + } + + Session.reset(new DIASession(DiaSession)); + return PDB_ErrorCode::Success; +} + uint64_t DIASession::getLoadAddress() const { uint64_t LoadAddress; bool success = (S_OK == Session->get_loadAddress(&LoadAddress)); @@ -95,6 +140,24 @@ std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const { return PDBSymbol::create(*this, std::move(RawSymbol)); } +std::unique_ptr<PDBSymbol> +DIASession::findSymbolByAddress(uint64_t Address) const { + CComPtr<IDiaSymbol> Symbol; + if (S_OK != Session->findSymbolByVA(Address, SymTagNull, &Symbol)) + return nullptr; + auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol); + return PDBSymbol::create(*this, std::move(RawSymbol)); +} + +std::unique_ptr<IPDBEnumLineNumbers> +DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const { + CComPtr<IDiaEnumLineNumbers> LineNumbers; + if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers)) + return nullptr; + + return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers); +} + std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const { CComPtr<IDiaEnumSourceFiles> Files; if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) diff --git a/llvm/lib/DebugInfo/PDB/PDB.cpp b/llvm/lib/DebugInfo/PDB/PDB.cpp index a07396d1a17..13201bbaa64 100644 --- a/llvm/lib/DebugInfo/PDB/PDB.cpp +++ b/llvm/lib/DebugInfo/PDB/PDB.cpp @@ -20,11 +20,20 @@ using namespace llvm; -PDB_ErrorCode llvm::createPDBReader(PDB_ReaderType Type, StringRef Path, - std::unique_ptr<IPDBSession> &Session) { +PDB_ErrorCode llvm::loadDataForPDB(PDB_ReaderType Type, StringRef Path, + std::unique_ptr<IPDBSession> &Session) { // Create the correct concrete instance type based on the value of Type. #if HAVE_DIA_SDK return DIASession::createFromPdb(Path, Session); #endif return PDB_ErrorCode::NoPdbImpl; } + +PDB_ErrorCode llvm::loadDataForEXE(PDB_ReaderType Type, StringRef Path, + std::unique_ptr<IPDBSession> &Session) { +// Create the correct concrete instance type based on the value of Type. +#if HAVE_DIA_SDK + return DIASession::createFromExe(Path, Session); +#endif + return PDB_ErrorCode::NoPdbImpl; +} |

