[compiler-rt] [llvm] [ORC][Runtime] Add `dlupdate` for elf (PR #110406)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 16 21:14:57 PDT 2024


https://github.com/SahilPatidar updated https://github.com/llvm/llvm-project/pull/110406

>From dd95f3dc7561e47c9c4dacb275051d6525c84f91 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
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 dec8d1e5bbc31e..3d7da18e3045b9 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<int32_t(SPSExecutorAddr)>::handle(
diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp
index 24cc6e1ef11778..0adf10a2a02200 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<std::recursive_mutex> &JDStatesLock,
                          PerJITDylibState &JDS,
                          ELFNixJITDylibDepInfoMap &DepInfo);
+  Error dlupdateImpl(void *DSOHandle, int Mode);
+  Error dlupdateFull(std::unique_lock<std::recursive_mutex> &JDStatesLock,
+                     PerJITDylibState &JDS);
+
   Error dlcloseImpl(void *DSOHandle);
   Error dlcloseInitialize(std::unique_lock<std::recursive_mutex> &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<std::recursive_mutex> 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<StringError>(ErrStream.str());
+  }
+
+  if (!JDS->referenced())
+    return make_error<StringError>("Dylib must be referenced");
+
+  if (auto Err = dlupdateFull(Lock, *JDS))
+    return Err;
+
+  return Error::success();
+}
+
+Error ELFNixPlatformRuntimeState::dlupdateFull(
+    std::unique_lock<std::recursive_mutex> &JDStatesLock,
+    PerJITDylibState &JDS) {
+  // Call back to the JIT to push the initializers.
+  Expected<ELFNixJITDylibDepInfoMap> DepInfo((ELFNixJITDylibDepInfoMap()));
+  // Unlock so that we can accept the initializer update.
+  JDStatesLock.unlock();
+  if (auto Err = WrapperFunction<SPSExpected<SPSELFNixJITDylibDepInfoMap>(
+          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<std::recursive_mutex> 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 5ecbdf0cb9c86f..0e72cc865aecc2 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 401ed525fd5cfe..9bb63f3fe864b3 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<StringError>("dlupdate failed",
                                        inconvertibleErrorCode());
-      return Error::success();
+      return E;
     }
     return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
                                            DSOHandles[&JD], JD.getName(),

>From d9313d3bf22900954677908c809555b22cd28b29 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
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 0adf10a2a02200..4df772e6e3aa02 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<StringError>("Dylib must be referenced");
+    return make_error<StringError>("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 <patidarsahil2001 at gmail.com>
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 9bb63f3fe864b3..e7acdf8603a6be 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 <patidarsahil2001 at gmail.com>
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 610ecbff5c5c4d..18736a430ed9b4 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 <patidarsahil2001 at gmail.com>
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 4df772e6e3aa02..6473139e931d82 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<std::recursive_mutex> &JDStatesLock,
                          PerJITDylibState &JDS,
                          ELFNixJITDylibDepInfoMap &DepInfo);
-  Error dlupdateImpl(void *DSOHandle, int Mode);
+  Error dlupdateImpl(void *DSOHandle);
   Error dlupdateFull(std::unique_lock<std::recursive_mutex> &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<std::recursive_mutex> 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 0e72cc865aecc2..0d61cbb948019c 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 e7acdf8603a6be..34a574e0477d99 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<SPSDLUpdateSig>(WrapperAddr->getAddress(),
                                                  result, DSOHandles[&JD]);
-      if (E)
-        return E;
-      else if (result)
+      if (result)
         return make_error<StringError>("dlupdate failed",
                                        inconvertibleErrorCode());
       return E;



More information about the llvm-commits mailing list