[compiler-rt] [llvm] [ORC][Runtime] Add `dlupdate` for MachO (PR #97441)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 26 23:31:56 PDT 2024
https://github.com/SahilPatidar updated https://github.com/llvm/llvm-project/pull/97441
>From 93a7cd44a7c25a33679af0fd181e3fca414b6186 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 29 Jun 2024 16:53:53 +0530
Subject: [PATCH 1/7] [ORC][Runtime] Add `dlupdate` for MachO
---
compiler-rt/lib/orc/dlfcn_wrapper.cpp | 12 ++
compiler-rt/lib/orc/macho_platform.cpp | 152 ++++++++++++++++++
compiler-rt/lib/orc/macho_platform.h | 1 +
llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h | 2 +
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 9 +-
.../lib/ExecutionEngine/Orc/MachOPlatform.cpp | 1 +
6 files changed, 176 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
index ece63da2cb48e..b2c4857e31392 100644
--- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp
+++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
@@ -20,6 +20,7 @@ using namespace __orc_rt;
extern "C" const char *__orc_rt_jit_dlerror();
extern "C" void *__orc_rt_jit_dlopen(const char *path, int mode);
+extern "C" void *__orc_rt_jit_dlupdate(const char *path, int mode);
extern "C" int __orc_rt_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
@@ -41,6 +42,17 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
.release();
}
+ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
+__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
+ return WrapperFunction<SPSExecutorAddr(SPSString, int32_t)>::handle(
+ ArgData, ArgSize,
+ [](const std::string &Path, int32_t mode) {
+ return ExecutorAddr::fromPtr(
+ __orc_rt_jit_dlupdate(Path.c_str(), mode));
+ })
+ .release();
+}
+
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
__orc_rt_jit_dlclose_wrapper(const char *ArgData, size_t ArgSize) {
return WrapperFunction<int32_t(SPSExecutorAddr)>::handle(
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 340846f5f9001..9233b33e6a5ec 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -330,6 +330,7 @@ class MachOPlatformRuntimeState {
const char *dlerror();
void *dlopen(std::string_view Name, int Mode);
+ void *dlupdate(std::string_view Name, int Mode);
int dlclose(void *DSOHandle);
void *dlsym(void *DSOHandle, const char *Symbol);
@@ -377,6 +378,12 @@ class MachOPlatformRuntimeState {
Error dlopenInitialize(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo);
+ Expected<void *> dlupdateImpl(std::string_view Path, int Mode);
+ Error dlupdateFull(std::unique_lock<std::mutex> &JDStatesLock,
+ JITDylibState &JDS);
+ Error dlupdateInitialize(std::unique_lock<std::mutex> &JDStatesLock,
+ JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo);
+
Error dlcloseImpl(void *DSOHandle);
Error dlcloseDeinitialize(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS);
@@ -786,6 +793,21 @@ void *MachOPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
}
}
+void *MachOPlatformRuntimeState::dlupdate(std::string_view Path, int Mode) {
+ ORC_RT_DEBUG({
+ std::string S(Path.data(), Path.size());
+ printdbg("MachOPlatform::dlupdate(\"%s\")\n", S.c_str());
+ });
+ std::lock_guard<std::recursive_mutex> Lock(DyldAPIMutex);
+ if (auto H = dlupdateImpl(Path, Mode))
+ return *H;
+ else {
+ // FIXME: Make dlerror thread safe.
+ DLFcnError = toString(H.takeError());
+ return nullptr;
+ }
+}
+
int MachOPlatformRuntimeState::dlclose(void *DSOHandle) {
ORC_RT_DEBUG({
auto *JDS = getJITDylibStateByHeader(DSOHandle);
@@ -1236,6 +1258,132 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
return Error::success();
}
+Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(std::string_view Path,
+ int Mode) {
+ std::unique_lock<std::mutex> Lock(JDStatesMutex);
+
+ // Try to find JITDylib state by name.
+ auto *JDS = getJITDylibStateByName(Path);
+
+ if (!JDS)
+ return make_error<StringError>("No registered JTIDylib for path " +
+ std::string(Path.data(), Path.size()));
+
+ // If this JITDylib is unsealed, or this is the first dlopen then run
+ // full dlopen path (update deps, push and run initializers, update ref
+ // counts on all JITDylibs in the dep tree).
+ if (!JDS->referenced() || !JDS->Sealed) {
+ if (auto Err = dlupdateFull(Lock, *JDS))
+ return std::move(Err);
+ }
+
+ // Return the header address.
+ return JDS->Header;
+}
+
+Error MachOPlatformRuntimeState::dlupdateFull(
+ std::unique_lock<std::mutex> &JDStatesLock, JITDylibState &JDS) {
+ // Call back to the JIT to push the initializers.
+ Expected<MachOJITDylibDepInfoMap> DepInfo((MachOJITDylibDepInfoMap()));
+ // Unlock so that we can accept the initializer update.
+ JDStatesLock.unlock();
+ if (auto Err = WrapperFunction<SPSExpected<SPSMachOJITDylibDepInfoMap>(
+ SPSExecutorAddr)>::call(&__orc_rt_macho_push_initializers_tag,
+ DepInfo, ExecutorAddr::fromPtr(JDS.Header)))
+ return Err;
+ JDStatesLock.lock();
+
+ if (!DepInfo)
+ return DepInfo.takeError();
+
+ if (auto Err = dlupdateInitialize(JDStatesLock, JDS, *DepInfo))
+ return Err;
+
+ if (!DepInfo->empty()) {
+ ORC_RT_DEBUG({
+ printdbg("Unrecognized dep-info key headers in dlupdate of %s\n",
+ JDS.Name.c_str());
+ });
+ std::ostringstream ErrStream;
+ ErrStream << "Encountered unrecognized dep-info key headers "
+ "while processing dlupdate of "
+ << JDS.Name;
+ return make_error<StringError>(ErrStream.str());
+ }
+
+ return Error::success();
+}
+
+Error MachOPlatformRuntimeState::dlupdateInitialize(
+ std::unique_lock<std::mutex> &JDStatesLock, JITDylibState &JDS,
+ MachOJITDylibDepInfoMap &DepInfo) {
+ ORC_RT_DEBUG({
+ printdbg("MachOPlatformRuntimeState::dlupdateInitialize(\"%s\")\n",
+ JDS.Name.c_str());
+ });
+
+ // If the header is not present in the dep map then assume that we
+ // already processed it earlier in the dlopenInitialize traversal and
+ // return.
+ // TODO: Keep a visited set instead so that we can error out on missing
+ // entries?
+ auto I = DepInfo.find(ExecutorAddr::fromPtr(JDS.Header));
+ if (I == DepInfo.end())
+ return Error::success();
+
+ auto DI = std::move(I->second);
+ DepInfo.erase(I);
+
+ // We don't need to re-initialize sealed JITDylibs that have already been
+ // initialized. Just check that their dep-map entry is empty as expected.
+ if (JDS.Sealed) {
+ if (!DI.DepHeaders.empty()) {
+ std::ostringstream ErrStream;
+ ErrStream << "Sealed JITDylib " << JDS.Header
+ << " already has registered dependencies";
+ return make_error<StringError>(ErrStream.str());
+ }
+ if (JDS.referenced())
+ return Error::success();
+ } else
+ JDS.Sealed = DI.Sealed;
+
+ // This is an unsealed or newly sealed JITDylib. Run initializers.
+ std::vector<JITDylibState *> OldDeps;
+ std::swap(JDS.Deps, OldDeps);
+ JDS.Deps.reserve(DI.DepHeaders.size());
+ for (auto DepHeaderAddr : DI.DepHeaders) {
+ auto *DepJDS = getJITDylibStateByHeader(DepHeaderAddr.toPtr<void *>());
+ if (!DepJDS) {
+ std::ostringstream ErrStream;
+ ErrStream << "Encountered unrecognized dep header "
+ << DepHeaderAddr.toPtr<void *>() << " while initializing "
+ << JDS.Name;
+ return make_error<StringError>(ErrStream.str());
+ }
+
+ if (auto Err = dlupdateInitialize(JDStatesLock, *DepJDS, DepInfo))
+ return Err;
+ }
+
+ // Initialize this JITDylib.
+ if (auto Err = registerObjCRegistrationObjects(JDS))
+ return Err;
+ if (auto Err = runModInits(JDStatesLock, JDS))
+ return Err;
+
+ // Decrement old deps.
+ // FIXME: We should probably continue and just report deinitialize errors
+ // here.
+ for (auto *DepJDS : OldDeps) {
+ if (!DepJDS->referenced())
+ if (auto Err = dlcloseDeinitialize(JDStatesLock, *DepJDS))
+ return Err;
+ }
+
+ return Error::success();
+}
+
Error MachOPlatformRuntimeState::dlcloseImpl(void *DSOHandle) {
std::unique_lock<std::mutex> Lock(JDStatesMutex);
@@ -1509,6 +1657,10 @@ void *__orc_rt_macho_jit_dlopen(const char *path, int mode) {
return MachOPlatformRuntimeState::get().dlopen(path, mode);
}
+void *__orc_rt_macho_jit_dlupdate(const char *path, int mode) {
+ return MachOPlatformRuntimeState::get().dlupdate(path, mode);
+}
+
int __orc_rt_macho_jit_dlclose(void *dso_handle) {
return MachOPlatformRuntimeState::get().dlclose(dso_handle);
}
diff --git a/compiler-rt/lib/orc/macho_platform.h b/compiler-rt/lib/orc/macho_platform.h
index 3b2242ab27ce8..ae9c8b487262a 100644
--- a/compiler-rt/lib/orc/macho_platform.h
+++ b/compiler-rt/lib/orc/macho_platform.h
@@ -24,6 +24,7 @@ ORC_RT_INTERFACE void __orc_rt_macho_cxa_finalize(void *dso_handle);
// dlfcn functions.
ORC_RT_INTERFACE const char *__orc_rt_macho_jit_dlerror();
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlopen(const char *path, int mode);
+ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlupdate(const char *path, int mode);
ORC_RT_INTERFACE int __orc_rt_macho_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlsym(void *dso_handle,
const char *symbol);
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index 3a71ddc88ce95..b42f13bf3fca8 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -22,6 +22,7 @@
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ThreadPool.h"
+#include "llvm/ADT/SmallSet.h"
#include <variant>
namespace llvm {
@@ -620,6 +621,7 @@ class ORCPlatformSupport : public LLJIT::PlatformSupport {
private:
orc::LLJIT &J;
DenseMap<orc::JITDylib *, orc::ExecutorAddr> DSOHandles;
+ SmallPtrSet<JITDylib const *, 8> InitializedDylib;
};
} // End namespace orc
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 568b2ececaa09..56339cfa359b1 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -611,9 +611,16 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
auto &ES = J.getExecutionSession();
auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
[](const JITDylibSearchOrder &SO) { return SO; });
+ StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
+ if (ES.getTargetTriple().isOSBinFormatMachO()) {
+ if (InitializedDylib.contains(&JD))
+ WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
+ else
+ InitializedDylib.insert(&JD);
+ }
if (auto WrapperAddr = ES.lookup(
- MainSearchOrder, J.mangleAndIntern("__orc_rt_jit_dlopen_wrapper"))) {
+ MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], JD.getName(),
int32_t(ORC_RT_RTLD_LAZY));
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index b477a48af2906..80a75988b9112 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -425,6 +425,7 @@ MachOPlatform::standardRuntimeUtilityAliases() {
{"___orc_rt_run_program", "___orc_rt_macho_run_program"},
{"___orc_rt_jit_dlerror", "___orc_rt_macho_jit_dlerror"},
{"___orc_rt_jit_dlopen", "___orc_rt_macho_jit_dlopen"},
+ {"___orc_rt_jit_dlupdate", "___orc_rt_macho_jit_dlupdate"},
{"___orc_rt_jit_dlclose", "___orc_rt_macho_jit_dlclose"},
{"___orc_rt_jit_dlsym", "___orc_rt_macho_jit_dlsym"},
{"___orc_rt_log_error", "___orc_rt_log_error_to_stderr"}};
>From 3d16e5c04c559d456dd70e13c4ab736c85d1e574 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Tue, 2 Jul 2024 17:02:20 +0530
Subject: [PATCH 2/7] Modify `dlupdate` to take `DSOHandle` instead of a path.
---
compiler-rt/lib/orc/dlfcn_wrapper.cpp | 8 +-
compiler-rt/lib/orc/macho_platform.cpp | 103 +++++--------------------
compiler-rt/lib/orc/macho_platform.h | 2 +-
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 11 ++-
4 files changed, 34 insertions(+), 90 deletions(-)
diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
index b2c4857e31392..a6ed7545807c8 100644
--- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp
+++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
@@ -20,7 +20,7 @@ using namespace __orc_rt;
extern "C" const char *__orc_rt_jit_dlerror();
extern "C" void *__orc_rt_jit_dlopen(const char *path, int mode);
-extern "C" void *__orc_rt_jit_dlupdate(const char *path, int mode);
+extern "C" void *__orc_rt_jit_dlupdate(void *dso_handle, int mode);
extern "C" int __orc_rt_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
@@ -44,11 +44,11 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSExecutorAddr(SPSString, int32_t)>::handle(
+ return WrapperFunction<SPSExecutorAddr(SPSExecutorAddr, int32_t)>::handle(
ArgData, ArgSize,
- [](const std::string &Path, int32_t mode) {
+ [](ExecutorAddr &DSOHandle, int32_t mode) {
return ExecutorAddr::fromPtr(
- __orc_rt_jit_dlupdate(Path.c_str(), mode));
+ __orc_rt_jit_dlupdate(DSOHandle.toPtr<void *>(), mode));
})
.release();
}
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 9233b33e6a5ec..353e2fa8ae313 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -330,7 +330,7 @@ class MachOPlatformRuntimeState {
const char *dlerror();
void *dlopen(std::string_view Name, int Mode);
- void *dlupdate(std::string_view Name, int Mode);
+ void *dlupdate(void *DSOHandle, int Mode);
int dlclose(void *DSOHandle);
void *dlsym(void *DSOHandle, const char *Symbol);
@@ -378,7 +378,7 @@ class MachOPlatformRuntimeState {
Error dlopenInitialize(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo);
- Expected<void *> dlupdateImpl(std::string_view Path, int Mode);
+ Expected<void *> dlupdateImpl(void *DSOHandle, int Mode);
Error dlupdateFull(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS);
Error dlupdateInitialize(std::unique_lock<std::mutex> &JDStatesLock,
@@ -793,13 +793,13 @@ void *MachOPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
}
}
-void *MachOPlatformRuntimeState::dlupdate(std::string_view Path, int Mode) {
+void *MachOPlatformRuntimeState::dlupdate(void *DSOHandle, int Mode) {
ORC_RT_DEBUG({
- std::string S(Path.data(), Path.size());
- printdbg("MachOPlatform::dlupdate(\"%s\")\n", S.c_str());
+ std::string S;
+ printdbg("MachOPlatform::dlupdate(%p) (%s)\n", DSOHandle, S.c_str());
});
std::lock_guard<std::recursive_mutex> Lock(DyldAPIMutex);
- if (auto H = dlupdateImpl(Path, Mode))
+ if (auto H = dlupdateImpl(DSOHandle, Mode))
return *H;
else {
// FIXME: Make dlerror thread safe.
@@ -1258,21 +1258,23 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
return Error::success();
}
-Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(std::string_view Path,
+Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
int Mode) {
std::unique_lock<std::mutex> Lock(JDStatesMutex);
- // Try to find JITDylib state by name.
- auto *JDS = getJITDylibStateByName(Path);
+ // Try to find JITDylib state by DSOHandle.
+ auto *JDS = getJITDylibStateByHeader(DSOHandle);
- if (!JDS)
- return make_error<StringError>("No registered JTIDylib for path " +
- std::string(Path.data(), Path.size()));
+ if (!JDS) {
+ std::ostringstream ErrStream;
+ ErrStream << "No registered JITDylib for " << DSOHandle;
+ return make_error<StringError>(ErrStream.str());
+ }
- // If this JITDylib is unsealed, or this is the first dlopen then run
- // full dlopen path (update deps, push and run initializers, update ref
- // counts on all JITDylibs in the dep tree).
- if (!JDS->referenced() || !JDS->Sealed) {
+ if (!JDS->referenced())
+ return make_error<StringError>("dlupdate failed, JITDylib must be open.");
+
+ if (!JDS->Sealed) {
if (auto Err = dlupdateFull(Lock, *JDS))
return std::move(Err);
}
@@ -1299,18 +1301,6 @@ Error MachOPlatformRuntimeState::dlupdateFull(
if (auto Err = dlupdateInitialize(JDStatesLock, JDS, *DepInfo))
return Err;
- if (!DepInfo->empty()) {
- ORC_RT_DEBUG({
- printdbg("Unrecognized dep-info key headers in dlupdate of %s\n",
- JDS.Name.c_str());
- });
- std::ostringstream ErrStream;
- ErrStream << "Encountered unrecognized dep-info key headers "
- "while processing dlupdate of "
- << JDS.Name;
- return make_error<StringError>(ErrStream.str());
- }
-
return Error::success();
}
@@ -1322,65 +1312,12 @@ Error MachOPlatformRuntimeState::dlupdateInitialize(
JDS.Name.c_str());
});
- // If the header is not present in the dep map then assume that we
- // already processed it earlier in the dlopenInitialize traversal and
- // return.
- // TODO: Keep a visited set instead so that we can error out on missing
- // entries?
- auto I = DepInfo.find(ExecutorAddr::fromPtr(JDS.Header));
- if (I == DepInfo.end())
- return Error::success();
-
- auto DI = std::move(I->second);
- DepInfo.erase(I);
-
- // We don't need to re-initialize sealed JITDylibs that have already been
- // initialized. Just check that their dep-map entry is empty as expected.
- if (JDS.Sealed) {
- if (!DI.DepHeaders.empty()) {
- std::ostringstream ErrStream;
- ErrStream << "Sealed JITDylib " << JDS.Header
- << " already has registered dependencies";
- return make_error<StringError>(ErrStream.str());
- }
- if (JDS.referenced())
- return Error::success();
- } else
- JDS.Sealed = DI.Sealed;
-
- // This is an unsealed or newly sealed JITDylib. Run initializers.
- std::vector<JITDylibState *> OldDeps;
- std::swap(JDS.Deps, OldDeps);
- JDS.Deps.reserve(DI.DepHeaders.size());
- for (auto DepHeaderAddr : DI.DepHeaders) {
- auto *DepJDS = getJITDylibStateByHeader(DepHeaderAddr.toPtr<void *>());
- if (!DepJDS) {
- std::ostringstream ErrStream;
- ErrStream << "Encountered unrecognized dep header "
- << DepHeaderAddr.toPtr<void *>() << " while initializing "
- << JDS.Name;
- return make_error<StringError>(ErrStream.str());
- }
-
- if (auto Err = dlupdateInitialize(JDStatesLock, *DepJDS, DepInfo))
- return Err;
- }
-
// Initialize this JITDylib.
if (auto Err = registerObjCRegistrationObjects(JDS))
return Err;
if (auto Err = runModInits(JDStatesLock, JDS))
return Err;
- // Decrement old deps.
- // FIXME: We should probably continue and just report deinitialize errors
- // here.
- for (auto *DepJDS : OldDeps) {
- if (!DepJDS->referenced())
- if (auto Err = dlcloseDeinitialize(JDStatesLock, *DepJDS))
- return Err;
- }
-
return Error::success();
}
@@ -1657,8 +1594,8 @@ void *__orc_rt_macho_jit_dlopen(const char *path, int mode) {
return MachOPlatformRuntimeState::get().dlopen(path, mode);
}
-void *__orc_rt_macho_jit_dlupdate(const char *path, int mode) {
- return MachOPlatformRuntimeState::get().dlupdate(path, mode);
+void *__orc_rt_macho_jit_dlupdate(void *dso_handle, int mode) {
+ return MachOPlatformRuntimeState::get().dlupdate(dso_handle, mode);
}
int __orc_rt_macho_jit_dlclose(void *dso_handle) {
diff --git a/compiler-rt/lib/orc/macho_platform.h b/compiler-rt/lib/orc/macho_platform.h
index ae9c8b487262a..c17331739aed4 100644
--- a/compiler-rt/lib/orc/macho_platform.h
+++ b/compiler-rt/lib/orc/macho_platform.h
@@ -24,7 +24,7 @@ ORC_RT_INTERFACE void __orc_rt_macho_cxa_finalize(void *dso_handle);
// dlfcn functions.
ORC_RT_INTERFACE const char *__orc_rt_macho_jit_dlerror();
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlopen(const char *path, int mode);
-ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlupdate(const char *path, int mode);
+ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlupdate(void *dso_handle, int mode);
ORC_RT_INTERFACE int __orc_rt_macho_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE void *__orc_rt_macho_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 56339cfa359b1..374365882318d 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -601,6 +601,7 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
using llvm::orc::shared::SPSExecutorAddr;
using llvm::orc::shared::SPSString;
using SPSDLOpenSig = SPSExecutorAddr(SPSString, int32_t);
+ using SPSDLUpdateSig = SPSExecutorAddr(SPSExecutorAddr, int32_t);
enum dlopen_mode : int32_t {
ORC_RT_RTLD_LAZY = 0x1,
ORC_RT_RTLD_NOW = 0x2,
@@ -612,15 +613,21 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
auto MainSearchOrder = J.getMainJITDylib().withLinkOrderDo(
[](const JITDylibSearchOrder &SO) { return SO; });
StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
+ bool dlupdate = false;
if (ES.getTargetTriple().isOSBinFormatMachO()) {
- if (InitializedDylib.contains(&JD))
+ if (InitializedDylib.contains(&JD)) {
WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
- else
+ dlupdate = true;
+ } else
InitializedDylib.insert(&JD);
}
if (auto WrapperAddr = ES.lookup(
MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
+ if (dlupdate)
+ return ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
+ DSOHandles[&JD], DSOHandles[&JD],
+ int32_t(ORC_RT_RTLD_LAZY));
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], JD.getName(),
int32_t(ORC_RT_RTLD_LAZY));
>From a9ec1aa5d2039d9b4661ade1ef77ae1e0322db44 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 3 Jul 2024 09:30:53 +0530
Subject: [PATCH 3/7] Refactor code.
---
compiler-rt/lib/orc/macho_platform.cpp | 7 ++++---
llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h | 2 +-
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 353e2fa8ae313..f229e155853a8 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -380,9 +380,10 @@ class MachOPlatformRuntimeState {
Expected<void *> dlupdateImpl(void *DSOHandle, int Mode);
Error dlupdateFull(std::unique_lock<std::mutex> &JDStatesLock,
- JITDylibState &JDS);
+ JITDylibState &JDS);
Error dlupdateInitialize(std::unique_lock<std::mutex> &JDStatesLock,
- JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo);
+ JITDylibState &JDS,
+ MachOJITDylibDepInfoMap &DepInfo);
Error dlcloseImpl(void *DSOHandle);
Error dlcloseDeinitialize(std::unique_lock<std::mutex> &JDStatesLock,
@@ -1259,7 +1260,7 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
}
Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
- int Mode) {
+ int Mode) {
std::unique_lock<std::mutex> Lock(JDStatesMutex);
// Try to find JITDylib state by DSOHandle.
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index b42f13bf3fca8..2660b9f74f405 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -13,6 +13,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H
#define LLVM_EXECUTIONENGINE_ORC_LLJIT_H
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
@@ -22,7 +23,6 @@
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ThreadPool.h"
-#include "llvm/ADT/SmallSet.h"
#include <variant>
namespace llvm {
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 374365882318d..75c8d0dd74c16 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -622,8 +622,8 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
InitializedDylib.insert(&JD);
}
- if (auto WrapperAddr = ES.lookup(
- MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
+ if (auto WrapperAddr =
+ ES.lookup(MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
if (dlupdate)
return ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], DSOHandles[&JD],
>From 99969487416e14630f9e7d5cd36271c900bd5ec5 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Fri, 5 Jul 2024 14:58:33 +0530
Subject: [PATCH 4/7] Fix deinitialize issue, This change ensures that the
`deinitialize` operation correctly removes the `JITDylib` from the set of
initialized `JITDylibs`.
---
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index 75c8d0dd74c16..0f8b9d3a3bbd4 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -654,6 +654,7 @@ Error ORCPlatformSupport::deinitialize(orc::JITDylib &JD) {
return make_error<StringError>("dlclose failed",
inconvertibleErrorCode());
DSOHandles.erase(&JD);
+ InitializedDylib.erase(&JD);
} else
return WrapperAddr.takeError();
return Error::success();
>From 7ca77fd9597d633614f82398031e5803637e82d6 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 6 Jul 2024 09:29:28 +0530
Subject: [PATCH 5/7] Remove the unused `DepInfo` argument from
`dlupdateInitialize`.
---
compiler-rt/lib/orc/macho_platform.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index f229e155853a8..a7e7a0b0da689 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -382,8 +382,7 @@ class MachOPlatformRuntimeState {
Error dlupdateFull(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS);
Error dlupdateInitialize(std::unique_lock<std::mutex> &JDStatesLock,
- JITDylibState &JDS,
- MachOJITDylibDepInfoMap &DepInfo);
+ JITDylibState &JDS);
Error dlcloseImpl(void *DSOHandle);
Error dlcloseDeinitialize(std::unique_lock<std::mutex> &JDStatesLock,
@@ -1299,15 +1298,14 @@ Error MachOPlatformRuntimeState::dlupdateFull(
if (!DepInfo)
return DepInfo.takeError();
- if (auto Err = dlupdateInitialize(JDStatesLock, JDS, *DepInfo))
+ if (auto Err = dlupdateInitialize(JDStatesLock, JDS))
return Err;
return Error::success();
}
Error MachOPlatformRuntimeState::dlupdateInitialize(
- std::unique_lock<std::mutex> &JDStatesLock, JITDylibState &JDS,
- MachOJITDylibDepInfoMap &DepInfo) {
+ std::unique_lock<std::mutex> &JDStatesLock, JITDylibState &JDS) {
ORC_RT_DEBUG({
printdbg("MachOPlatformRuntimeState::dlupdateInitialize(\"%s\")\n",
JDS.Name.c_str());
>From c09a2a802060178b40a1c44e478bceb93efb1449 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 27 Jul 2024 11:35:30 +0530
Subject: [PATCH 6/7] Modify dlupdate to return error code instead of
dso_handle
---
compiler-rt/lib/orc/dlfcn_wrapper.cpp | 7 +++----
compiler-rt/lib/orc/macho_platform.cpp | 24 +++++++++++-------------
compiler-rt/lib/orc/macho_platform.h | 2 +-
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 16 +++++++++++-----
4 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
index a6ed7545807c8..9a6096930c553 100644
--- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp
+++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp
@@ -20,7 +20,7 @@ using namespace __orc_rt;
extern "C" const char *__orc_rt_jit_dlerror();
extern "C" void *__orc_rt_jit_dlopen(const char *path, int mode);
-extern "C" void *__orc_rt_jit_dlupdate(void *dso_handle, int mode);
+extern "C" int __orc_rt_jit_dlupdate(void *dso_handle, int mode);
extern "C" int __orc_rt_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
@@ -44,11 +44,10 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
- return WrapperFunction<SPSExecutorAddr(SPSExecutorAddr, int32_t)>::handle(
+ return WrapperFunction<int32_t(SPSExecutorAddr, int32_t)>::handle(
ArgData, ArgSize,
[](ExecutorAddr &DSOHandle, int32_t mode) {
- return ExecutorAddr::fromPtr(
- __orc_rt_jit_dlupdate(DSOHandle.toPtr<void *>(), mode));
+ return __orc_rt_jit_dlupdate(DSOHandle.toPtr<void *>(), mode);
})
.release();
}
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index a7e7a0b0da689..8c68347bf1551 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -330,7 +330,7 @@ class MachOPlatformRuntimeState {
const char *dlerror();
void *dlopen(std::string_view Name, int Mode);
- void *dlupdate(void *DSOHandle, int Mode);
+ int dlupdate(void *DSOHandle, int Mode);
int dlclose(void *DSOHandle);
void *dlsym(void *DSOHandle, const char *Symbol);
@@ -378,7 +378,7 @@ class MachOPlatformRuntimeState {
Error dlopenInitialize(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo);
- Expected<void *> dlupdateImpl(void *DSOHandle, int Mode);
+ Error dlupdateImpl(void *DSOHandle, int Mode);
Error dlupdateFull(std::unique_lock<std::mutex> &JDStatesLock,
JITDylibState &JDS);
Error dlupdateInitialize(std::unique_lock<std::mutex> &JDStatesLock,
@@ -793,19 +793,18 @@ void *MachOPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
}
}
-void *MachOPlatformRuntimeState::dlupdate(void *DSOHandle, int Mode) {
+int MachOPlatformRuntimeState::dlupdate(void *DSOHandle, int Mode) {
ORC_RT_DEBUG({
std::string S;
printdbg("MachOPlatform::dlupdate(%p) (%s)\n", DSOHandle, S.c_str());
});
std::lock_guard<std::recursive_mutex> Lock(DyldAPIMutex);
- if (auto H = dlupdateImpl(DSOHandle, Mode))
- return *H;
- else {
+ if (auto Err = dlupdateImpl(DSOHandle, Mode)) {
// FIXME: Make dlerror thread safe.
- DLFcnError = toString(H.takeError());
- return nullptr;
+ DLFcnError = toString(std::move(Err));
+ return -1;
}
+ return 0;
}
int MachOPlatformRuntimeState::dlclose(void *DSOHandle) {
@@ -1258,7 +1257,7 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
return Error::success();
}
-Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
+Error MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
int Mode) {
std::unique_lock<std::mutex> Lock(JDStatesMutex);
@@ -1276,11 +1275,10 @@ Expected<void *> MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
if (!JDS->Sealed) {
if (auto Err = dlupdateFull(Lock, *JDS))
- return std::move(Err);
+ return Err;
}
- // Return the header address.
- return JDS->Header;
+ return Error::success();
}
Error MachOPlatformRuntimeState::dlupdateFull(
@@ -1593,7 +1591,7 @@ void *__orc_rt_macho_jit_dlopen(const char *path, int mode) {
return MachOPlatformRuntimeState::get().dlopen(path, mode);
}
-void *__orc_rt_macho_jit_dlupdate(void *dso_handle, int mode) {
+int __orc_rt_macho_jit_dlupdate(void *dso_handle, int mode) {
return MachOPlatformRuntimeState::get().dlupdate(dso_handle, mode);
}
diff --git a/compiler-rt/lib/orc/macho_platform.h b/compiler-rt/lib/orc/macho_platform.h
index c17331739aed4..b297befc3881d 100644
--- a/compiler-rt/lib/orc/macho_platform.h
+++ b/compiler-rt/lib/orc/macho_platform.h
@@ -24,7 +24,7 @@ ORC_RT_INTERFACE void __orc_rt_macho_cxa_finalize(void *dso_handle);
// dlfcn functions.
ORC_RT_INTERFACE const char *__orc_rt_macho_jit_dlerror();
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlopen(const char *path, int mode);
-ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlupdate(void *dso_handle, int mode);
+ORC_RT_INTERFACE int __orc_rt_macho_jit_dlupdate(void *dso_handle, int mode);
ORC_RT_INTERFACE int __orc_rt_macho_jit_dlclose(void *dso_handle);
ORC_RT_INTERFACE void *__orc_rt_macho_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 0f8b9d3a3bbd4..4327d94dcc71f 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -601,7 +601,7 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
using llvm::orc::shared::SPSExecutorAddr;
using llvm::orc::shared::SPSString;
using SPSDLOpenSig = SPSExecutorAddr(SPSString, int32_t);
- using SPSDLUpdateSig = SPSExecutorAddr(SPSExecutorAddr, int32_t);
+ using SPSDLUpdateSig = int32_t(SPSExecutorAddr, int32_t);
enum dlopen_mode : int32_t {
ORC_RT_RTLD_LAZY = 0x1,
ORC_RT_RTLD_NOW = 0x2,
@@ -624,10 +624,16 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
if (auto WrapperAddr =
ES.lookup(MainSearchOrder, J.mangleAndIntern(WrapperToCall))) {
- if (dlupdate)
- return ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
- DSOHandles[&JD], DSOHandles[&JD],
- int32_t(ORC_RT_RTLD_LAZY));
+ if (dlupdate) {
+ int32_t result;
+ auto E = ES.callSPSWrapper<SPSDLUpdateSig>(WrapperAddr->getAddress(),
+ result, DSOHandles[&JD],
+ int32_t(ORC_RT_RTLD_LAZY));
+ if (result)
+ return make_error<StringError>("dlupdate failed",
+ inconvertibleErrorCode());
+ return E;
+ }
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], JD.getName(),
int32_t(ORC_RT_RTLD_LAZY));
>From 34469c21046b90069fd19bcd4f9c99afeb830c0c Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 27 Jul 2024 12:01:06 +0530
Subject: [PATCH 7/7] Fix code format
---
compiler-rt/lib/orc/macho_platform.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp
index 8c68347bf1551..3e9ea4b65c870 100644
--- a/compiler-rt/lib/orc/macho_platform.cpp
+++ b/compiler-rt/lib/orc/macho_platform.cpp
@@ -1257,8 +1257,7 @@ Error MachOPlatformRuntimeState::dlopenInitialize(
return Error::success();
}
-Error MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle,
- int Mode) {
+Error MachOPlatformRuntimeState::dlupdateImpl(void *DSOHandle, int Mode) {
std::unique_lock<std::mutex> Lock(JDStatesMutex);
// Try to find JITDylib state by DSOHandle.
More information about the llvm-commits
mailing list