diff --git a/openmp/libomptarget/include/PluginManager.h b/openmp/libomptarget/include/PluginManager.h index 6af99efa32a0c..0b0974709b525 100644 --- a/openmp/libomptarget/include/PluginManager.h +++ b/openmp/libomptarget/include/PluginManager.h @@ -150,6 +150,24 @@ struct PluginManager { HostPtrToTableMapTy HostPtrToTableMap; std::mutex TblMapMtx; ///< For HostPtrToTableMap + // Work around for plugins that call dlopen on shared libraries that call + // tgt_register_lib during their initialisation. Stash the pointers in a + // vector until the plugins are all initialised and then register them. + bool delayRegisterLib(__tgt_bin_desc *Desc) { + if (RTLsLoaded) + return false; + DelayedBinDesc.push_back(Desc); + return true; + } + + void registerDelayedLibraries() { + // Only called by libomptarget constructor + RTLsLoaded = true; + for (auto *Desc : DelayedBinDesc) + __tgt_register_lib(Desc); + DelayedBinDesc.clear(); + } + /// Return the number of usable devices. int getNumDevices() { return getExclusiveDevicesAccessor()->size(); } @@ -178,6 +196,9 @@ struct PluginManager { void addRequirements(int64_t Flags) { Requirements.addRequirements(Flags); } private: + bool RTLsLoaded = false; + llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc; + // List of all plugin adaptors, in use or not. llvm::SmallVector> PluginAdaptors; diff --git a/openmp/libomptarget/src/interface.cpp b/openmp/libomptarget/src/interface.cpp index 777dc07943aa6..d92f40ce1d14e 100644 --- a/openmp/libomptarget/src/interface.cpp +++ b/openmp/libomptarget/src/interface.cpp @@ -46,6 +46,9 @@ EXTERN void __tgt_register_requires(int64_t Flags) { /// adds a target shared library to the target execution image EXTERN void __tgt_register_lib(__tgt_bin_desc *Desc) { TIMESCOPE(); + if (PM->delayRegisterLib(Desc)) + return; + PM->registerLib(Desc); } diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp index 27db7034d8956..5eb1c553df491 100644 --- a/openmp/libomptarget/src/rtl.cpp +++ b/openmp/libomptarget/src/rtl.cpp @@ -51,6 +51,7 @@ __attribute__((constructor(101))) void init() { PM->init(); Profiler::get(); + PM->registerDelayedLibraries(); } __attribute__((destructor(101))) void deinit() { diff --git a/openmp/libomptarget/test/Inputs/empty.c b/openmp/libomptarget/test/Inputs/empty.c deleted file mode 100644 index 8b137891791fe..0000000000000 --- a/openmp/libomptarget/test/Inputs/empty.c +++ /dev/null @@ -1 +0,0 @@ - diff --git a/openmp/libomptarget/test/offloading/bug60119.c b/openmp/libomptarget/test/offloading/bug60119.c deleted file mode 100644 index e32f1ccd59881..0000000000000 --- a/openmp/libomptarget/test/offloading/bug60119.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %clang-generic -fPIC -shared %S/../Inputs/empty.c -o %T/liba.so -// RUN: %clang-generic -fPIC -shared %S/../Inputs/empty.c -o %T/libb.so -// RUN: %clang-generic -rpath %T -L %T -l a -l b %s -o %t -// RUN: %t - -int main() {}