From: Zachary Turner Date: Fri, 17 Apr 2015 22:40:36 +0000 (+0000) Subject: [PDB] Support executables and source/line info. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9d74bda3e373b8a98efe461188470b35c56128cb;p=oota-llvm.git [PDB] Support executables and source/line info. Previously DebugInfoPDB could only load data for a PDB given a path to the PDB. It could not open an EXE and find the matching PDB and verify it matched, etc. This patch adds support for that so that we can simply load debug information for a PDB directly. Additionally, this patch extends DebugInfoPDB to support getting source and line information for symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235237 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index 6c72c3e6fc6..b8d1f1ca5bf 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -21,12 +21,19 @@ public: static PDB_ErrorCode createFromPdb(StringRef Path, std::unique_ptr &Session); + static PDB_ErrorCode createFromExe(StringRef Path, + std::unique_ptr &Session); uint64_t getLoadAddress() const override; void setLoadAddress(uint64_t Address) override; std::unique_ptr getGlobalScope() const override; std::unique_ptr getSymbolById(uint32_t SymbolId) const override; + std::unique_ptr + findSymbolByAddress(uint64_t Address) const override; + std::unique_ptr + findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override; + std::unique_ptr getAllSourceFiles() const override; std::unique_ptr getSourceFilesForCompiland( const PDBSymbolCompiland &Compiland) const override; diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 60d6f62068e..f1debc02bc6 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -43,6 +43,11 @@ public: return std::unique_ptr(ConcreteSymbol); } + virtual std::unique_ptr + findSymbolByAddress(uint64_t Address) const = 0; + virtual std::unique_ptr + findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0; + virtual std::unique_ptr getAllSourceFiles() const = 0; virtual std::unique_ptr getSourceFilesForCompiland(const PDBSymbolCompiland &Compiland) const = 0; diff --git a/include/llvm/DebugInfo/PDB/PDB.h b/include/llvm/DebugInfo/PDB/PDB.h index 67878e9ccf6..5df3be85e38 100644 --- a/include/llvm/DebugInfo/PDB/PDB.h +++ b/include/llvm/DebugInfo/PDB/PDB.h @@ -16,8 +16,11 @@ namespace llvm { class StringRef; -PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path, - std::unique_ptr &Session); +PDB_ErrorCode loadDataForPDB(PDB_ReaderType Type, StringRef Path, + std::unique_ptr &Session); + +PDB_ErrorCode loadDataForEXE(PDB_ReaderType Type, StringRef Path, + std::unique_ptr &Session); } #endif diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index 686e08f81a1..2d19e792d3d 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -21,6 +21,7 @@ class PDBSymbol; class IPDBDataStream; template class IPDBEnumChildren; +class IPDBLineNumber; class IPDBRawSymbol; class IPDBSession; class IPDBSourceFile; @@ -28,6 +29,7 @@ class IPDBSourceFile; typedef IPDBEnumChildren IPDBEnumSymbols; typedef IPDBEnumChildren IPDBEnumSourceFiles; typedef IPDBEnumChildren IPDBEnumDataStreams; +typedef IPDBEnumChildren IPDBEnumLineNumbers; class PDBSymbolExe; class PDBSymbolCompiland; @@ -426,7 +428,8 @@ enum class PDB_ErrorCode { InvalidParameter, AlreadyLoaded, UnknownError, - NoMemory + NoMemory, + DebugInfoMismatch }; struct VersionInfo { diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp index 4966bea96f6..e3e3fc05ab3 100644 --- a/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/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 &Session) { + CComPtr DiaDataSource; + CComPtr 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(&DiaDataSource)); + if (FAILED(Result)) + return PDB_ErrorCode::NoPdbImpl; + + llvm::SmallVector Path16; + if (!llvm::convertUTF8ToUTF16String(Path, Path16)) + return PDB_ErrorCode::InvalidPath; + + const wchar_t *Path16Str = reinterpret_cast(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 DIASession::getSymbolById(uint32_t SymbolId) const { return PDBSymbol::create(*this, std::move(RawSymbol)); } +std::unique_ptr +DIASession::findSymbolByAddress(uint64_t Address) const { + CComPtr Symbol; + if (S_OK != Session->findSymbolByVA(Address, SymTagNull, &Symbol)) + return nullptr; + auto RawSymbol = llvm::make_unique(*this, Symbol); + return PDBSymbol::create(*this, std::move(RawSymbol)); +} + +std::unique_ptr +DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const { + CComPtr LineNumbers; + if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers)) + return nullptr; + + return llvm::make_unique(LineNumbers); +} + std::unique_ptr DIASession::getAllSourceFiles() const { CComPtr Files; if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files)) diff --git a/lib/DebugInfo/PDB/PDB.cpp b/lib/DebugInfo/PDB/PDB.cpp index a07396d1a17..13201bbaa64 100644 --- a/lib/DebugInfo/PDB/PDB.cpp +++ b/lib/DebugInfo/PDB/PDB.cpp @@ -20,11 +20,20 @@ using namespace llvm; -PDB_ErrorCode llvm::createPDBReader(PDB_ReaderType Type, StringRef Path, - std::unique_ptr &Session) { +PDB_ErrorCode llvm::loadDataForPDB(PDB_ReaderType Type, StringRef Path, + std::unique_ptr &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 &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; +} diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 78535ec0be9..597683291ff 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -101,7 +101,7 @@ cl::opt NoEnumDefs("no-enum-definitions", static void dumpInput(StringRef Path) { std::unique_ptr Session; PDB_ErrorCode Error = - llvm::createPDBReader(PDB_ReaderType::DIA, Path, Session); + llvm::loadDataForPDB(PDB_ReaderType::DIA, Path, Session); switch (Error) { case PDB_ErrorCode::Success: break; diff --git a/unittests/DebugInfo/PDB/PDBApiTest.cpp b/unittests/DebugInfo/PDB/PDBApiTest.cpp index 629c5f8bc0e..4f8e95d9078 100644 --- a/unittests/DebugInfo/PDB/PDBApiTest.cpp +++ b/unittests/DebugInfo/PDB/PDBApiTest.cpp @@ -72,6 +72,16 @@ class MockSession : public IPDBSession { getSourceFileById(uint32_t SymbolId) const override { return nullptr; } + + std::unique_ptr + findSymbolByAddress(uint64_t Address) const override { + return nullptr; + } + std::unique_ptr + findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override { + return nullptr; + } + std::unique_ptr getAllSourceFiles() const override { return nullptr; }