Skip to content

[ORC][Runtime] Add dlupdate for elf #110406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler-rt/lib/orc/dlfcn_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
62 changes: 62 additions & 0 deletions compiler-rt/lib/orc/elfnix_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class ELFNixPlatformRuntimeState {

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);

Expand Down Expand Up @@ -136,6 +137,10 @@ class ELFNixPlatformRuntimeState {
Error dlopenInitialize(std::unique_lock<std::recursive_mutex> &JDStatesLock,
PerJITDylibState &JDS,
ELFNixJITDylibDepInfoMap &DepInfo);
Error dlupdateImpl(void *DSOHandle);
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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -523,6 +537,50 @@ Error ELFNixPlatformRuntimeState::dlopenInitialize(
return Error::success();
}

Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle) {
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>("dlupdate failed, JITDylib must be open.");

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);
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/orc/elfnix_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"}};
Expand Down
9 changes: 4 additions & 5 deletions llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,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;
Expand All @@ -635,12 +636,10 @@ 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 Error::success();
return E;
}
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
DSOHandles[&JD], JD.getName(),
Expand Down
Loading