summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-04-17 22:40:36 +0000
committerZachary Turner <zturner@google.com>2015-04-17 22:40:36 +0000
commit4b08354b0ebb5551048138148f61911bc1232491 (patch)
tree5f268cad63b67dcd46c702b1f9f51c31ec39e696 /llvm/lib/DebugInfo
parentd0a2482870218dce13c629f5acce96d8dafffcfd (diff)
downloadbcm5719-llvm-4b08354b0ebb5551048138148f61911bc1232491.tar.gz
bcm5719-llvm-4b08354b0ebb5551048138148f61911bc1232491.zip
[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. llvm-svn: 235237
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp63
-rw-r--r--llvm/lib/DebugInfo/PDB/PDB.cpp13
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;
+}
OpenPOWER on IntegriCloud