[llvm] 906a91a - [MCJIT] Check for RuntimeDyld errors in MCJIT::finalizeLoadedModules.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 13 13:58:53 PDT 2020


Author: Lang Hames
Date: 2020-03-13T13:58:41-07:00
New Revision: 906a91aa4d52beb1cd3b8b5ce55f768060996620

URL: https://github.com/llvm/llvm-project/commit/906a91aa4d52beb1cd3b8b5ce55f768060996620
DIFF: https://github.com/llvm/llvm-project/commit/906a91aa4d52beb1cd3b8b5ce55f768060996620.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm-c/ExecutionEngine.h
    llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
    llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
    llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm-c/ExecutionEngine.h b/llvm/include/llvm-c/ExecutionEngine.h
index f31b97ad7623..c5fc9bdb4d07 100644
--- a/llvm/include/llvm-c/ExecutionEngine.h
+++ b/llvm/include/llvm-c/ExecutionEngine.h
@@ -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)(

diff  --git a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
index 9b41ed4391cf..2562da7cf60b 100644
--- a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -158,6 +158,8 @@ class ExecutionEngine {
   /// 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 @@ class ExecutionEngine {
   /// 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.
   ///

diff  --git a/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index ff1e8050c7e7..addec6871fa1 100644
--- a/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -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 {

diff  --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 9c3d0d539841..d2af987946e8 100644
--- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -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


        


More information about the llvm-commits mailing list