mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
[llvm-pdbdump] Better error handling.
Previously it was impossible to distinguish between "There is no PDB implementation for this platform" and "I tried to load the PDB, but couldn't find the file", making it hard to figure out if you built llvm-pdbdump incorrectly or if you just mistyped a file name. This patch adds proper error handling so that we can know exactly what went wrong. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230868 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ce770dda2c
commit
e09af84db5
@ -19,7 +19,8 @@ class DIASession : public IPDBSession {
|
||||
public:
|
||||
explicit DIASession(CComPtr<IDiaSession> DiaSession);
|
||||
|
||||
static DIASession *createFromPdb(StringRef Path);
|
||||
static PDB_ErrorCode createFromPdb(StringRef Path,
|
||||
std::unique_ptr<IPDBSession> &Session);
|
||||
|
||||
uint64_t getLoadAddress() const override;
|
||||
void setLoadAddress(uint64_t Address) override;
|
||||
|
@ -16,8 +16,8 @@
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
|
||||
std::unique_ptr<IPDBSession> createPDBReader(PDB_ReaderType Type,
|
||||
StringRef Path);
|
||||
PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path,
|
||||
std::unique_ptr<IPDBSession> &Session);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -418,6 +418,17 @@ enum class PDB_RegisterId {
|
||||
|
||||
enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
|
||||
|
||||
enum class PDB_ErrorCode {
|
||||
Success,
|
||||
NoPdbImpl,
|
||||
InvalidPath,
|
||||
InvalidFileFormat,
|
||||
InvalidParameter,
|
||||
AlreadyLoaded,
|
||||
UnknownError,
|
||||
NoMemory
|
||||
};
|
||||
|
||||
struct VersionInfo {
|
||||
uint32_t Major;
|
||||
uint32_t Minor;
|
||||
|
@ -23,28 +23,45 @@ namespace {}
|
||||
|
||||
DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
|
||||
|
||||
DIASession *DIASession::createFromPdb(StringRef Path) {
|
||||
CComPtr<IDiaDataSource> DataSource;
|
||||
CComPtr<IDiaSession> Session;
|
||||
PDB_ErrorCode DIASession::createFromPdb(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 *>(&DataSource));
|
||||
HRESULT Result = ::CoCreateInstance(
|
||||
CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
|
||||
reinterpret_cast<LPVOID *>(&DiaDataSource));
|
||||
if (FAILED(Result))
|
||||
return nullptr;
|
||||
return PDB_ErrorCode::NoPdbImpl;
|
||||
|
||||
llvm::SmallVector<UTF16, 128> Path16;
|
||||
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
|
||||
return nullptr;
|
||||
return PDB_ErrorCode::InvalidPath;
|
||||
|
||||
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
|
||||
if (FAILED(DataSource->loadDataFromPdb(Path16Str)))
|
||||
return nullptr;
|
||||
if (FAILED(Result = DiaDataSource->loadDataFromPdb(Path16Str))) {
|
||||
if (Result == E_PDB_NOT_FOUND)
|
||||
return PDB_ErrorCode::InvalidPath;
|
||||
else if (Result == E_PDB_FORMAT)
|
||||
return PDB_ErrorCode::InvalidFileFormat;
|
||||
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(DataSource->openSession(&Session)))
|
||||
return nullptr;
|
||||
return new DIASession(Session);
|
||||
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 {
|
||||
|
@ -20,11 +20,11 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
std::unique_ptr<IPDBSession> llvm::createPDBReader(PDB_ReaderType Type,
|
||||
StringRef Path) {
|
||||
PDB_ErrorCode llvm::createPDBReader(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 std::unique_ptr<DIASession>(DIASession::createFromPdb(Path));
|
||||
return DIASession::createFromPdb(Path, Session);
|
||||
#endif
|
||||
return nullptr;
|
||||
return PDB_ErrorCode::NoPdbImpl;
|
||||
}
|
||||
|
@ -66,11 +66,26 @@ cl::opt<bool> ClassDefs("class-definitions",
|
||||
}
|
||||
|
||||
static void dumpInput(StringRef Path) {
|
||||
std::unique_ptr<IPDBSession> Session(
|
||||
llvm::createPDBReader(PDB_ReaderType::DIA, Path));
|
||||
if (!Session) {
|
||||
outs() << "Unable to create PDB reader. Check that a valid implementation";
|
||||
outs() << " is available for your platform.";
|
||||
std::unique_ptr<IPDBSession> Session;
|
||||
PDB_ErrorCode Error =
|
||||
llvm::createPDBReader(PDB_ReaderType::DIA, Path, Session);
|
||||
switch (Error) {
|
||||
case PDB_ErrorCode::Success:
|
||||
break;
|
||||
case PDB_ErrorCode::NoPdbImpl:
|
||||
outs() << "Reading PDBs is not supported on this platform.\n";
|
||||
return;
|
||||
case PDB_ErrorCode::InvalidPath:
|
||||
outs() << "Unable to load PDB at '" << Path
|
||||
<< "'. Check that the file exists and is readable.\n";
|
||||
return;
|
||||
case PDB_ErrorCode::InvalidFileFormat:
|
||||
outs() << "Unable to load PDB at '" << Path
|
||||
<< "'. The file has an unrecognized format.\n";
|
||||
return;
|
||||
default:
|
||||
outs() << "Unable to load PDB at '" << Path
|
||||
<< "'. An unknown error occured.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user