diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp index 89f6f227e280f96357777a578248e380adf82c3e..f67be10133e524c2d6f089116d5b85ac10e8691c 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 475b7affb2e72a5009939f6102480444de622ce6..dbff847ef0be3203c740df602cdae5fcb0050352 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 987725d2a8327c13de72a2918f32db6d6fab4fa2..db11ff4835d7ae92edbfce1980ad003a62b2bbed 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 b2e44dae5cb0fdc9d56ab8e2f8461dc13a92f374..4948402ec08499a9c99fb1612405641fe31c3212 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\"");