From 23989e77a2f9938d4516568eef9e904d59a8c307 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Tue, 4 Mar 2014 18:15:14 +0100
Subject: [PATCH] Keep trying to remap __cxa_atexit until succeeded.

__cxa_atexit is generated by clang::CodeGen upon seeing the first static
destructor. Instead of trying to provoke that we just continue to search for it.
---
 .../lib/Interpreter/IncrementalExecutor.cpp   | 46 ++++++-------------
 .../lib/Interpreter/IncrementalExecutor.h     | 14 +++---
 .../cling/lib/Interpreter/IncrementalParser.h |  2 +-
 .../cling/lib/Interpreter/Interpreter.cpp     |  1 -
 4 files changed, 22 insertions(+), 41 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
index 89f6f227e28..f67be10133e 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
@@ -76,39 +76,16 @@ void IncrementalExecutor::shuttingDown() {
 }
 
 void IncrementalExecutor::remapCXAAtExit() {
-  assert(!m_CxaAtExitRemapped && "__cxa_at_exit already remapped.");
-  llvm::Function* clingAtExit
-    = m_engine->FindFunctionNamed("cling_cxa_atexit");
-  assert(clingAtExit && "cling_cxa_atexit must exist.");
+  if (m_CxaAtExitRemapped)
+    return;
 
   llvm::Function* atExit = m_engine->FindFunctionNamed("__cxa_atexit");
-  if (!atExit) {
-    // Inject __cxa_atexit into module
-    llvm::Type* retTy = 0;
-    llvm::Type* voidPtrTy = 0;
-    if (sizeof(int) == 4) {
-      retTy = llvm::Type::getInt32Ty(llvm::getGlobalContext());
-      voidPtrTy = llvm::Type::getInt32PtrTy(llvm::getGlobalContext());
-    } else if (sizeof(int) == 8) {
-      retTy = llvm::Type::getInt64Ty(llvm::getGlobalContext());
-      voidPtrTy = llvm::Type::getInt64PtrTy(llvm::getGlobalContext());
-    } else {
-      assert(retTy && "Unsupported sizeof(int)!");
-      retTy = llvm::Type::getInt64Ty(llvm::getGlobalContext());
-      voidPtrTy = llvm::Type::getInt64PtrTy(llvm::getGlobalContext());
-    }
+  if (!atExit)
+    return;
 
-    llvm::SmallVector<llvm::Type*, 3> argTy;
-    argTy.push_back(voidPtrTy);
-    argTy.push_back(voidPtrTy);
-    argTy.push_back(voidPtrTy);
-    llvm::FunctionType* cxaatexitTy
-      = llvm::FunctionType::get(retTy, argTy, false /*varArg*/);
-    llvm::Function* atexitFunc
-      = llvm::Function::Create(cxaatexitTy, llvm::GlobalValue::InternalLinkage,
-                               "__cxa_atexit", 0 /*module*/);
-    m_engine->addGlobalMapping(atexitFunc, clingAtExit);
-  }
+  llvm::Function* clingAtExit
+    = m_engine->FindFunctionNamed("cling_cxa_atexit");
+  assert(clingAtExit && "cling_cxa_atexit must exist.");
 
   void* clingAtExitAddr = m_engine->getPointerToFunction(clingAtExit);
   assert(clingAtExitAddr && "cannot find cling_cxa_atexit");
@@ -194,6 +171,8 @@ IncrementalExecutor::executeFunction(llvm::StringRef funcname,
   // We don't care whether something was unresolved before.
   m_unresolvedSymbols.clear();
 
+  remapCXAAtExit();
+
   llvm::Function* f = m_engine->FindFunctionNamed(funcname.str().c_str());
   if (!f) {
     llvm::errs() << "IncrementalExecutor::executeFunction: "
@@ -276,6 +255,7 @@ IncrementalExecutor::runStaticInitializersOnce(llvm::Module* m) {
 
     // Execute the ctor/dtor function!
     if (llvm::Function *F = llvm::dyn_cast<llvm::Function>(FP)) {
+      remapCXAAtExit();
       m_engine->getPointerToFunction(F);
       // check if there is any unresolved symbol in the list
       if (!m_unresolvedSymbols.empty()) {
@@ -340,7 +320,7 @@ IncrementalExecutor::addSymbol(const char* symbolName,  void* symbolAddress) {
 
 void* IncrementalExecutor::getAddressOfGlobal(llvm::Module* m,
                                               llvm::StringRef symbolName,
-                                              bool* fromJIT /*=0*/) const {
+                                              bool* fromJIT /*=0*/) {
   // Return a symbol's address, and whether it was jitted.
   void* address
     = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
@@ -352,13 +332,15 @@ void* IncrementalExecutor::getAddressOfGlobal(llvm::Module* m,
     if (!gvar)
       return 0;
 
+    remapCXAAtExit();
     address = m_engine->getPointerToGlobal(gvar);
   }
   return address;
 }
 
 void*
-IncrementalExecutor::getPointerToGlobalFromJIT(const llvm::GlobalValue& GV)const{
+IncrementalExecutor::getPointerToGlobalFromJIT(const llvm::GlobalValue& GV) {
+  remapCXAAtExit();
   if (void* addr = m_engine->getPointerToGlobalIfAvailable(&GV))
     return addr;
 
diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.h b/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
index 475b7affb2e..dbff847ef0b 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
+++ b/interpreter/cling/lib/Interpreter/IncrementalExecutor.h
@@ -141,11 +141,6 @@ namespace cling {
     ///
     void shuttingDown();
 
-    ///\brief Remaps the __cxa_at_exit with a interpreter-controlled one, so 
-    /// that the interpreter can call the object destructors at the right time.
-    ///
-    void remapCXAAtExit();
-
     ///\brief Gets the address of an existing global and whether it was JITted.
     ///
     /// JIT symbols might not be immediately convertible to e.g. a function
@@ -156,14 +151,14 @@ namespace cling {
     ///\param[out] fromJIT - whether the symbol was JITted.
     ///
     void* getAddressOfGlobal(llvm::Module* m, llvm::StringRef mangledName,
-                             bool* fromJIT = 0) const;
+                             bool* fromJIT = 0);
 
     ///\brief Return the address of a global from the ExecutionEngine (as
     /// opposed to dynamic libraries). Forces the emission of the symbol if
     /// it has not happened yet.
     ///
     ///param[in] GV - global value for which the address will be returned.
-    void* getPointerToGlobalFromJIT(const llvm::GlobalValue& GV) const;
+    void* getPointerToGlobalFromJIT(const llvm::GlobalValue& GV);
 
     llvm::ExecutionEngine* getExecutionEngine() const {
       if (!m_engine)
@@ -177,6 +172,11 @@ namespace cling {
                         const cling::Transaction* clingT);
 
   private:
+    ///\brief Remaps the __cxa_at_exit with a interpreter-controlled one, so 
+    /// that the interpreter can call the object destructors at the right time.
+    ///
+    void remapCXAAtExit();
+
     static void* HandleMissingFunction(const std::string&);
     static void* NotifyLazyFunctionCreators(const std::string&);
 
diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.h b/interpreter/cling/lib/Interpreter/IncrementalParser.h
index 987725d2a83..db11ff4835d 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalParser.h
+++ b/interpreter/cling/lib/Interpreter/IncrementalParser.h
@@ -103,7 +103,7 @@ namespace cling {
                       const char* llvmdir);
     ~IncrementalParser();
 
-     void Initialize();
+    void Initialize();
     clang::CompilerInstance* getCI() const { return m_CI.get(); }
     clang::Parser* getParser() const { return m_Parser.get(); }
     clang::CodeGenerator* getCodeGenerator() const { return m_CodeGen.get(); }
diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index b2e44dae5cb..4948402ec08 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -233,7 +233,6 @@ namespace cling {
           "cling::Interpreter *gCling=(cling::Interpreter*)"
                     << (uintptr_t)this << ";} }";
         declare(initializer.str());
-        m_Executor->remapCXAAtExit();
       }
 
       declare("#include \"cling/Interpreter/ValuePrinter.h\"");
-- 
GitLab