Skip to content

Commit dd95f3d

Browse files
committed
Add dlupdate for elf
1 parent 1b4a173 commit dd95f3d

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

compiler-rt/lib/orc/dlfcn_wrapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) {
4242
.release();
4343
}
4444

45-
#ifdef __APPLE__
45+
#ifndef _WIN32
4646
ORC_RT_INTERFACE orc_rt_CWrapperFunctionResult
4747
__orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) {
4848
return WrapperFunction<int32_t(SPSExecutorAddr)>::handle(

compiler-rt/lib/orc/elfnix_platform.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class ELFNixPlatformRuntimeState {
105105

106106
const char *dlerror();
107107
void *dlopen(std::string_view Name, int Mode);
108+
int dlupdate(void *DSOHandle, int Mode);
108109
int dlclose(void *DSOHandle);
109110
void *dlsym(void *DSOHandle, std::string_view Symbol);
110111

@@ -136,6 +137,10 @@ class ELFNixPlatformRuntimeState {
136137
Error dlopenInitialize(std::unique_lock<std::recursive_mutex> &JDStatesLock,
137138
PerJITDylibState &JDS,
138139
ELFNixJITDylibDepInfoMap &DepInfo);
140+
Error dlupdateImpl(void *DSOHandle, int Mode);
141+
Error dlupdateFull(std::unique_lock<std::recursive_mutex> &JDStatesLock,
142+
PerJITDylibState &JDS);
143+
139144
Error dlcloseImpl(void *DSOHandle);
140145
Error dlcloseInitialize(std::unique_lock<std::recursive_mutex> &JDStatesLock,
141146
PerJITDylibState &JDS);
@@ -309,6 +314,15 @@ void *ELFNixPlatformRuntimeState::dlopen(std::string_view Path, int Mode) {
309314
}
310315
}
311316

317+
int ELFNixPlatformRuntimeState::dlupdate(void *DSOHandle, int Mode) {
318+
if (auto Err = dlupdateImpl(DSOHandle, Mode)) {
319+
// FIXME: Make dlerror thread safe.
320+
DLFcnError = toString(std::move(Err));
321+
return -1;
322+
}
323+
return 0;
324+
}
325+
312326
int ELFNixPlatformRuntimeState::dlclose(void *DSOHandle) {
313327
if (auto Err = dlcloseImpl(DSOHandle)) {
314328
DLFcnError = toString(std::move(Err));
@@ -523,6 +537,50 @@ Error ELFNixPlatformRuntimeState::dlopenInitialize(
523537
return Error::success();
524538
}
525539

540+
Error ELFNixPlatformRuntimeState::dlupdateImpl(void *DSOHandle, int Mode) {
541+
std::unique_lock<std::recursive_mutex> Lock(JDStatesMutex);
542+
543+
// Try to find JITDylib state by name.
544+
auto *JDS = getJITDylibStateByHeaderAddr(DSOHandle);
545+
546+
if (!JDS) {
547+
std::ostringstream ErrStream;
548+
ErrStream << "No registered JITDylib for " << DSOHandle;
549+
return make_error<StringError>(ErrStream.str());
550+
}
551+
552+
if (!JDS->referenced())
553+
return make_error<StringError>("Dylib must be referenced");
554+
555+
if (auto Err = dlupdateFull(Lock, *JDS))
556+
return Err;
557+
558+
return Error::success();
559+
}
560+
561+
Error ELFNixPlatformRuntimeState::dlupdateFull(
562+
std::unique_lock<std::recursive_mutex> &JDStatesLock,
563+
PerJITDylibState &JDS) {
564+
// Call back to the JIT to push the initializers.
565+
Expected<ELFNixJITDylibDepInfoMap> DepInfo((ELFNixJITDylibDepInfoMap()));
566+
// Unlock so that we can accept the initializer update.
567+
JDStatesLock.unlock();
568+
if (auto Err = WrapperFunction<SPSExpected<SPSELFNixJITDylibDepInfoMap>(
569+
SPSExecutorAddr)>::
570+
call(JITDispatch(&__orc_rt_elfnix_push_initializers_tag), DepInfo,
571+
ExecutorAddr::fromPtr(JDS.Header)))
572+
return Err;
573+
JDStatesLock.lock();
574+
575+
if (!DepInfo)
576+
return DepInfo.takeError();
577+
578+
if (auto Err = runInits(JDStatesLock, JDS))
579+
return Err;
580+
581+
return Error::success();
582+
}
583+
526584
Error ELFNixPlatformRuntimeState::dlcloseImpl(void *DSOHandle) {
527585

528586
std::unique_lock<std::recursive_mutex> Lock(JDStatesMutex);
@@ -765,6 +823,10 @@ void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode) {
765823
return ELFNixPlatformRuntimeState::get().dlopen(path, mode);
766824
}
767825

826+
int __orc_rt_elfnix_jit_dlupdate(void *dso_handle, int mode) {
827+
return ELFNixPlatformRuntimeState::get().dlupdate(dso_handle, mode);
828+
}
829+
768830
int __orc_rt_elfnix_jit_dlclose(void *dso_handle) {
769831
return ELFNixPlatformRuntimeState::get().dlclose(dso_handle);
770832
}

compiler-rt/lib/orc/elfnix_platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ORC_RT_INTERFACE void __orc_rt_elfnix_cxa_finalize(void *dso_handle);
2525
// dlfcn functions.
2626
ORC_RT_INTERFACE const char *__orc_rt_elfnix_jit_dlerror();
2727
ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlopen(const char *path, int mode);
28+
ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlupdate(void *dso_handle, int mode);
2829
ORC_RT_INTERFACE int __orc_rt_elfnix_jit_dlclose(void *dso_handle);
2930
ORC_RT_INTERFACE void *__orc_rt_elfnix_jit_dlsym(void *dso_handle,
3031
const char *symbol);

llvm/lib/ExecutionEngine/Orc/LLJIT.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,9 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
621621
[](const JITDylibSearchOrder &SO) { return SO; });
622622
StringRef WrapperToCall = "__orc_rt_jit_dlopen_wrapper";
623623
bool dlupdate = false;
624-
if (ES.getTargetTriple().isOSBinFormatMachO()) {
624+
const Triple &TT = ES.getTargetTriple();
625+
if (TT.isOSBinFormatMachO() ||
626+
TT.isOSBinFormatELF()) {
625627
if (InitializedDylib.contains(&JD)) {
626628
WrapperToCall = "__orc_rt_jit_dlupdate_wrapper";
627629
dlupdate = true;
@@ -640,7 +642,7 @@ Error ORCPlatformSupport::initialize(orc::JITDylib &JD) {
640642
else if (result)
641643
return make_error<StringError>("dlupdate failed",
642644
inconvertibleErrorCode());
643-
return Error::success();
645+
return E;
644646
}
645647
return ES.callSPSWrapper<SPSDLOpenSig>(WrapperAddr->getAddress(),
646648
DSOHandles[&JD], JD.getName(),

0 commit comments

Comments
 (0)