From dd95f3dc7561e47c9c4dacb275051d6525c84f91 Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Sat, 28 Sep 2024 17:46:35 +0530 Subject: [PATCH 1/5] Add `dlupdate` for elf --- compiler-rt/lib/orc/dlfcn_wrapper.cpp | 2 +- compiler-rt/lib/orc/elfnix_platform.cpp | 62 +++++++++++++++++++++++++ compiler-rt/lib/orc/elfnix_platform.h | 1 + llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 6 ++- 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp index dec8d1e5bbc31..3d7da18e3045b 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 24cc6e1ef1177..0adf10a2a0220 100644 --- a/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/compiler-rt/lib/orc/elfnix_platform.cpp @@ -105,6 +105,7 @@ class ELFNixPlatformRuntimeState { const char *dlerror(); void *dlopen(std::string_view Name, int Mode); + int dlupdate(void *DSOHandle, int Mode); int dlclose(void *DSOHandle); void *dlsym(void *DSOHandle, std::string_view Symbol); @@ -136,6 +137,10 @@ class ELFNixPlatformRuntimeState { Error dlopenInitialize(std::unique_lock &JDStatesLock, PerJITDylibState &JDS, ELFNixJITDylibDepInfoMap &DepInfo); + Error dlupdateImpl(void *DSOHandle, int Mode); + 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, int Mode) { + if (auto Err = dlupdateImpl(DSOHandle, Mode)) { + // 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, int Mode) { + 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("Dylib must be referenced"); + + 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, int mode) { + return ELFNixPlatformRuntimeState::get().dlupdate(dso_handle, mode); +} + 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 5ecbdf0cb9c86..0e72cc865aecc 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, int mode); 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/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 401ed525fd5cf..9bb63f3fe864b 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -621,7 +621,9 @@ 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; @@ -640,7 +642,7 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) { else if (result) return make_error("dlupdate failed", inconvertibleErrorCode()); - return Error::success(); + return E; } return ES.callSPSWrapper(WrapperAddr->getAddress(), DSOHandles[&JD], JD.getName(), From d9313d3bf22900954677908c809555b22cd28b29 Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Sun, 29 Sep 2024 10:52:05 +0530 Subject: [PATCH 2/5] Update error message --- compiler-rt/lib/orc/elfnix_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp index 0adf10a2a0220..4df772e6e3aa0 100644 --- a/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/compiler-rt/lib/orc/elfnix_platform.cpp @@ -550,7 +550,7 @@ Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle, int Mode) { } if (!JDS->referenced()) - return make_error("Dylib must be referenced"); + return make_error("dlupdate failed, JITDylib must be open."); if (auto Err = dlupdateFull(Lock, *JDS)) return Err; From 17756d42202c54d0fc172c9c2860df257ebdf588 Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Sun, 29 Sep 2024 10:59:36 +0530 Subject: [PATCH 3/5] Fix minor code format --- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 9bb63f3fe864b..e7acdf8603a6b 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -622,8 +622,7 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) { StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper"; bool dlupdate = false; const Triple &TT = ES.getTargetTriple(); - if (TT.isOSBinFormatMachO() || - TT.isOSBinFormatELF()) { + if (TT.isOSBinFormatMachO() || TT.isOSBinFormatELF()) { if (InitializedDylib.contains(&JD)) { WrapperToCall = "__orc_rt_jit_dlupdate_wrapper"; dlupdate = true; From 1b8dc2dd0c8d186b2e141e572f3b0bf4ba501623 Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Sun, 29 Sep 2024 14:29:10 +0530 Subject: [PATCH 4/5] Add dlupdate to ELFNixPlatform --- llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp index 610ecbff5c5c4..18736a430ed9b 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"}}; From 42a193c7d488e002b7ade75adae401746f40a64a Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Mon, 30 Sep 2024 16:43:28 +0530 Subject: [PATCH 5/5] Refactor dlupdate to remove the mode argument --- compiler-rt/lib/orc/elfnix_platform.cpp | 14 +++++++------- compiler-rt/lib/orc/elfnix_platform.h | 2 +- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp index 4df772e6e3aa0..6473139e931d8 100644 --- a/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/compiler-rt/lib/orc/elfnix_platform.cpp @@ -105,7 +105,7 @@ class ELFNixPlatformRuntimeState { const char *dlerror(); void *dlopen(std::string_view Name, int Mode); - int dlupdate(void *DSOHandle, int Mode); + int dlupdate(void *DSOHandle); int dlclose(void *DSOHandle); void *dlsym(void *DSOHandle, std::string_view Symbol); @@ -137,7 +137,7 @@ class ELFNixPlatformRuntimeState { Error dlopenInitialize(std::unique_lock &JDStatesLock, PerJITDylibState &JDS, ELFNixJITDylibDepInfoMap &DepInfo); - Error dlupdateImpl(void *DSOHandle, int Mode); + Error dlupdateImpl(void *DSOHandle); Error dlupdateFull(std::unique_lock &JDStatesLock, PerJITDylibState &JDS); @@ -314,8 +314,8 @@ void *ELFNixPlatformRuntimeState::dlopen(std::string_view Path, int Mode) { } } -int ELFNixPlatformRuntimeState::dlupdate(void *DSOHandle, int Mode) { - if (auto Err = dlupdateImpl(DSOHandle, Mode)) { +int ELFNixPlatformRuntimeState::dlupdate(void *DSOHandle) { + if (auto Err = dlupdateImpl(DSOHandle)) { // FIXME: Make dlerror thread safe. DLFcnError = toString(std::move(Err)); return -1; @@ -537,7 +537,7 @@ Error ELFNixPlatformRuntimeState::dlopenInitialize( return Error::success(); } -Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle, int Mode) { +Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle) { std::unique_lock Lock(JDStatesMutex); // Try to find JITDylib state by name. @@ -823,8 +823,8 @@ 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, int mode) { - return ELFNixPlatformRuntimeState::get().dlupdate(dso_handle, 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) { diff --git a/compiler-rt/lib/orc/elfnix_platform.h b/compiler-rt/lib/orc/elfnix_platform.h index 0e72cc865aecc..0d61cbb948019 100644 --- a/compiler-rt/lib/orc/elfnix_platform.h +++ b/compiler-rt/lib/orc/elfnix_platform.h @@ -25,7 +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, 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/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index e7acdf8603a6b..34a574e0477d9 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -636,9 +636,7 @@ 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 E;