static PDB_ErrorCode createFromPdb(StringRef Path,
std::unique_ptr<IPDBSession> &Session);
+ static PDB_ErrorCode createFromExe(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
+ std::unique_ptr<PDBSymbol>
+ findSymbolByAddress(uint64_t Address) const override;
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
+
std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override;
std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
const PDBSymbolCompiland &Compiland) const override;
#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"
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));
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))
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;
+}