diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp index dec8d1e5bbc3..3d7da18e3045 100644 --- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp +++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp @@ -42,7 +42,7 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) { .release(); } -#ifdef __APPLE__ +#ifndef _WIN32 ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult __orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) { return WrapperFunction::handle( diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp index 24cc6e1ef117..6473139e931d 100644 --- a/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/compiler-rt/lib/orc/elfnix_platform.cpp @@ -105,6 +105,7 @@ public: const char *dlerror(); void *dlopen(std::string_view Name, int Mode); + int dlupdate(void *DSOHandle); int dlclose(void *DSOHandle); void *dlsym(void *DSOHandle, std::string_view Symbol); @@ -136,6 +137,10 @@ private: Error dlopenInitialize(std::unique_lock &JDStatesLock, PerJITDylibState &JDS, ELFNixJITDylibDepInfoMap &DepInfo); + Error dlupdateImpl(void *DSOHandle); + Error dlupdateFull(std::unique_lock &JDStatesLock, + PerJITDylibState &JDS); + Error dlcloseImpl(void *DSOHandle); Error dlcloseInitialize(std::unique_lock &JDStatesLock, PerJITDylibState &JDS); @@ -309,6 +314,15 @@ void *ELFNixPlatformRuntimeState::dlopen(std::string_view Path, int Mode) { } } +int ELFNixPlatformRuntimeState::dlupdate(void *DSOHandle) { + if (auto Err = dlupdateImpl(DSOHandle)) { + // FIXME: Make dlerror thread safe. + DLFcnError = toString(std::move(Err)); + return -1; + } + return 0; +} + int ELFNixPlatformRuntimeState::dlclose(void *DSOHandle) { if (auto Err = dlcloseImpl(DSOHandle)) { DLFcnError = toString(std::move(Err)); @@ -523,6 +537,50 @@ Error ELFNixPlatformRuntimeState::dlopenInitialize( return Error::success(); } +Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle) { + std::unique_lock Lock(JDStatesMutex); + + // Try to find JITDylib state by name. + auto *JDS = getJITDylibStateByHeaderAddr(DSOHandle); + + if (!JDS) { + std::ostringstream ErrStream; + ErrStream << "No registered JITDylib for " << DSOHandle; + return make_error(ErrStream.str()); + } + + if (!JDS->referenced()) + return make_error("dlupdate failed, JITDylib must be open."); + + if (auto Err = dlupdateFull(Lock, *JDS)) + return Err; + + return Error::success(); +} + +Error ELFNixPlatformRuntimeState::dlupdateFull( + std::unique_lock &JDStatesLock, + PerJITDylibState &JDS) { + // Call back to the JIT to push the initializers. + Expected DepInfo((ELFNixJITDylibDepInfoMap())); + // Unlock so that we can accept the initializer update. + JDStatesLock.unlock(); + if (auto Err = WrapperFunction( + SPSExecutorAddr)>:: + call(JITDispatch(&__orc_rt_elfnix_push_initializers_tag), DepInfo, + ExecutorAddr::fromPtr(JDS.Header))) + return Err; + JDStatesLock.lock(); + + if (!DepInfo) + return DepInfo.takeError(); + + if (auto Err = runInits(JDStatesLock, JDS)) + return Err; + + return Error::success(); +} + Error ELFNixPlatformRuntimeState::dlcloseImpl(void *DSOHandle) { std::unique_lock Lock(JDStatesMutex); @@ -765,6 +823,10 @@ void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode) { return ELFNixPlatformRuntimeState::get().dlopen(path, mode); } +int __orc_rt_elfnix_jit_dlupdate(void *dso_handle) { + return ELFNixPlatformRuntimeState::get().dlupdate(dso_handle); +} + int __orc_rt_elfnix_jit_dlclose(void *dso_handle) { return ELFNixPlatformRuntimeState::get().dlclose(dso_handle); } diff --git a/compiler-rt/lib/orc/elfnix_platform.h b/compiler-rt/lib/orc/elfnix_platform.h index 5ecbdf0cb9c8..0d61cbb94801 100644 --- a/compiler-rt/lib/orc/elfnix_platform.h +++ b/compiler-rt/lib/orc/elfnix_platform.h @@ -25,6 +25,7 @@ ORC_RT_INTERFACE void __orc_rt_elfnix_cxa_finalize(void *dso_handle); // dlfcn functions. ORC_RT_INTERFACE const char *__orc_rt_elfnix_jit_dlerror(); ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode); +ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlupdate(void *dso_handle); ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlclose(void *dso_handle); ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlsym(void *dso_handle, const char *symbol); diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp index c8c341668ddd..6cea9845a340 100644 --- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp @@ -372,6 +372,7 @@ ELFNixPlatform::standardRuntimeUtilityAliases() { {"__orc_rt_run_program", "__orc_rt_elfnix_run_program"}, {"__orc_rt_jit_dlerror", "__orc_rt_elfnix_jit_dlerror"}, {"__orc_rt_jit_dlopen", "__orc_rt_elfnix_jit_dlopen"}, + {"__orc_rt_jit_dlupdate", "__orc_rt_elfnix_jit_dlupdate"}, {"__orc_rt_jit_dlclose", "__orc_rt_elfnix_jit_dlclose"}, {"__orc_rt_jit_dlsym", "__orc_rt_elfnix_jit_dlsym"}, {"__orc_rt_log_error", "__orc_rt_log_error_to_stderr"}}; diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index db39fec12e5f..b31f46295654 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -625,7 +625,8 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) { [](const JITDylibSearchOrder &SO) { return SO; }); StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper"; bool dlupdate = false; - if (ES.getTargetTriple().isOSBinFormatMachO()) { + const Triple &TT = ES.getTargetTriple(); + if (TT.isOSBinFormatMachO() || TT.isOSBinFormatELF()) { if (InitializedDylib.contains(&JD)) { WrapperToCall = "__orc_rt_jit_dlupdate_wrapper"; dlupdate = true; @@ -639,12 +640,10 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) { int32_t result; auto E = ES.callSPSWrapper(WrapperAddr->getAddress(), result, DSOHandles[&JD]); - if (E) - return E; - else if (result) + if (result) return make_error("dlupdate failed", inconvertibleErrorCode()); - return Error::success(); + return E; } return ES.callSPSWrapper(WrapperAddr->getAddress(), DSOHandles[&JD], JD.getName(),