Index: llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h =================================================================== --- llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -192,20 +192,18 @@ Error enable(JITDylib &JD, MangleAndInterner &Mangler); }; -/// An interface for Itanium __cxa_atexit interposer implementations. +/// An interface for Itanium __cxa_atexit, atexit interposer implementations. class ItaniumCXAAtExitSupport { public: - struct AtExitRecord { - void (*F)(void *); - void *Ctx; - }; + using AtExitHandler = std::function; - void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle); + void registerCxaAtExit(void (*F)(void *), void *Ctx, void *DSOHandle); + void registerAtExit(void (*F)(), void *DSOHandle); void runAtExits(void *DSOHandle); private: std::mutex AtExitsMutex; - DenseMap> AtExitRecords; + DenseMap> AtExitRecords; }; /// A utility class to expose symbols found via dlsym to the JIT. Index: llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -195,14 +195,19 @@ return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); } -void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx, - void *DSOHandle) { +void ItaniumCXAAtExitSupport::registerCxaAtExit(void (*F)(void *), void *Ctx, + void *DSOHandle) { std::lock_guard Lock(AtExitsMutex); - AtExitRecords[DSOHandle].push_back({F, Ctx}); + AtExitRecords[DSOHandle].push_back([F, Ctx]() { F(Ctx); }); +} + +void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void), void *DSOHandle) { + std::lock_guard Lock(AtExitsMutex); + AtExitRecords[DSOHandle].push_back(F); } void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) { - std::vector AtExitsToRun; + std::vector AtExitsToRun; { std::lock_guard Lock(AtExitsMutex); @@ -213,9 +218,8 @@ } } - while (!AtExitsToRun.empty()) { - AtExitsToRun.back().F(AtExitsToRun.back().Ctx); - AtExitsToRun.pop_back(); + for (auto I = AtExitsToRun.rbegin(); I != AtExitsToRun.rend(); ++I) { + (*I)(); } } Index: llvm/lib/ExecutionEngine/Orc/LLJIT.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -143,6 +143,9 @@ JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags::Exported); StdInterposes[J.mangleAndIntern("__lljit.cxa_atexit_helper")] = + JITEvaluatedSymbol(pointerToJITTargetAddress(registerCxaAtExitHelper), + JITSymbolFlags()); + StdInterposes[J.mangleAndIntern("__lljit.atexit_helper")] = JITEvaluatedSymbol(pointerToJITTargetAddress(registerAtExitHelper), JITSymbolFlags()); @@ -190,6 +193,14 @@ GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper", {PlatformInstanceDecl, DSOHandle}); + auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); + auto *AtExitCallbackTy = FunctionType::get(VoidTy, {}, false); + auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); + addHelperAndWrapper(*M, "atexit", + FunctionType::get(IntTy, {AtExitCallbackPtrTy}, false), + GlobalValue::HiddenVisibility, "__lljit.atexit_helper", + {PlatformInstanceDecl, DSOHandle}); + return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx))); } @@ -413,14 +424,23 @@ .takeError(); } - static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx, - void *DSOHandle) { + static void registerCxaAtExitHelper(void *Self, void (*F)(void *), void *Ctx, + void *DSOHandle) { + LLVM_DEBUG({ + dbgs() << "Registering cxa atexit function " << (void *)F << " for JD " + << (*static_cast(DSOHandle))->getName() << "\n"; + }); + static_cast(Self) + ->AtExitMgr.registerCxaAtExit(F, Ctx, DSOHandle); + } + + static void registerAtExitHelper(void *Self, void *DSOHandle, void (*F)()) { LLVM_DEBUG({ dbgs() << "Registering atexit function " << (void *)F << " for JD " << (*static_cast(DSOHandle))->getName() << "\n"; }); static_cast(Self)->AtExitMgr.registerAtExit( - F, Ctx, DSOHandle); + F, DSOHandle); } static void runAtExitsHelper(void *Self, void *DSOHandle) { @@ -450,12 +470,12 @@ auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT); auto *VoidTy = Type::getVoidTy(*Ctx); auto *BytePtrTy = PointerType::getUnqual(Int8Ty); - auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); - auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy); + auto *CxaAtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false); + auto *CxaAtExitCallbackPtrTy = PointerType::getUnqual(CxaAtExitCallbackTy); addHelperAndWrapper( *M, "__cxa_atexit", - FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, + FunctionType::get(IntTy, {CxaAtExitCallbackPtrTy, BytePtrTy, BytePtrTy}, false), GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper", {PlatformInstanceDecl});