mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-21 18:22:53 +01:00
[MCJIT] Check for RuntimeDyld errors in MCJIT::finalizeLoadedModules.
Patch based on https://reviews.llvm.org/D75912 by Alexander Shishkin. Thanks Alexander! To minimize disruption to existing clients, who may be relying on the fact that unused references to unresolved symbols do not generate an error, this patch makes error checking opt-in: Clients can call ExecutionEngine::hasError or LLVMExecutionEngineGetError to check whether and error has occurred. Differential revision: https://reviews.llvm.org/D75912
This commit is contained in:
parent
3f9596e9a9
commit
c3e7231c1f
@ -149,6 +149,11 @@ uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name);
|
||||
|
||||
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name);
|
||||
|
||||
/// Returns true on error, false on success. If true is returned then the error
|
||||
/// message is copied to OutStr and cleared in the ExecutionEngine instance.
|
||||
LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
|
||||
char **OutError);
|
||||
|
||||
/*===-- Operations on memory managers -------------------------------------===*/
|
||||
|
||||
typedef uint8_t *(*LLVMMemoryManagerAllocateCodeSectionCallback)(
|
||||
|
@ -158,6 +158,8 @@ protected:
|
||||
/// getMangledName - Get mangled name.
|
||||
std::string getMangledName(const GlobalValue *GV);
|
||||
|
||||
std::string ErrMsg;
|
||||
|
||||
public:
|
||||
/// lock - This lock protects the ExecutionEngine and MCJIT classes. It must
|
||||
/// be held while changing the internal state of any of those classes.
|
||||
@ -275,8 +277,20 @@ public:
|
||||
/// object have been relocated using mapSectionAddress. When this method is
|
||||
/// called the MCJIT execution engine will reapply relocations for a loaded
|
||||
/// object. This method has no effect for the interpeter.
|
||||
///
|
||||
/// Returns true on success, false on failure. Error messages can be retrieved
|
||||
/// by calling getError();
|
||||
virtual void finalizeObject() {}
|
||||
|
||||
/// Returns true if an error has been recorded.
|
||||
bool hasError() const { return !ErrMsg.empty(); }
|
||||
|
||||
/// Clear the error message.
|
||||
void clearErrorMessage() { ErrMsg.clear(); }
|
||||
|
||||
/// Returns the most recent error message.
|
||||
const std::string &getErrorMessage() const { return ErrMsg; }
|
||||
|
||||
/// runStaticConstructorsDestructors - This method is used to execute all of
|
||||
/// the static constructors or destructors for a program.
|
||||
///
|
||||
|
@ -308,6 +308,18 @@ uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
|
||||
return unwrap(EE)->getFunctionAddress(Name);
|
||||
}
|
||||
|
||||
LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
|
||||
char **OutError) {
|
||||
assert(OutError && "OutError must be non-null");
|
||||
auto *ExecEngine = unwrap(EE);
|
||||
if (ExecEngine->hasError()) {
|
||||
*OutError = strdup(ExecEngine->getErrorMessage().c_str());
|
||||
ExecEngine->clearErrorMessage();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*===-- Operations on memory managers -------------------------------------===*/
|
||||
|
||||
namespace {
|
||||
|
@ -239,6 +239,10 @@ void MCJIT::finalizeLoadedModules() {
|
||||
// Resolve any outstanding relocations.
|
||||
Dyld.resolveRelocations();
|
||||
|
||||
// Check for Dyld error.
|
||||
if (Dyld.hasError())
|
||||
ErrMsg = Dyld.getErrorString().str();
|
||||
|
||||
OwnedModules.markAllLoadedModulesAsFinalized();
|
||||
|
||||
// Register EH frame data for any module we own which has been loaded
|
||||
|
Loading…
Reference in New Issue
Block a user