1
0
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:
Lang Hames 2020-03-13 09:24:09 -07:00
parent 3f9596e9a9
commit c3e7231c1f
4 changed files with 35 additions and 0 deletions

View File

@ -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)(

View File

@ -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.
///

View File

@ -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 {

View File

@ -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