From ae9bc810fe1fa8c599ec54cc84ef7514fec474ca Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 24 Nov 2023 08:11:20 +0000 Subject: 8313616: support loading library members on AIX in os::dll_load Reviewed-by: phh Backport-of: 23fe2ece586d3ed750e905e1b71a2cd1da91f335 --- src/hotspot/os/aix/libodm_aix.cpp | 9 ++++++--- src/hotspot/os/aix/libperfstat_aix.cpp | 9 +++++---- src/hotspot/os/aix/os_aix.cpp | 15 +++++++++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/hotspot/os/aix/libodm_aix.cpp b/src/hotspot/os/aix/libodm_aix.cpp index db8e8a5d960..d62a94939a4 100644 --- a/src/hotspot/os/aix/libodm_aix.cpp +++ b/src/hotspot/os/aix/libodm_aix.cpp @@ -29,13 +29,16 @@ #include #include #include "runtime/arguments.hpp" +#include "runtime/os.hpp" dynamicOdm::dynamicOdm() { - const char *libodmname = "/usr/lib/libodm.a(shr_64.o)"; - _libhandle = dlopen(libodmname, RTLD_MEMBER | RTLD_NOW); + const char* libodmname = "/usr/lib/libodm.a(shr_64.o)"; + char ebuf[512]; + void* _libhandle = os::dll_load(libodmname, ebuf, sizeof(ebuf)); + if (!_libhandle) { - trcVerbose("Couldn't open %s", libodmname); + trcVerbose("Cannot load %s (error %s)", libodmname, ebuf); return; } _odm_initialize = (fun_odm_initialize )dlsym(_libhandle, "odm_initialize" ); diff --git a/src/hotspot/os/aix/libperfstat_aix.cpp b/src/hotspot/os/aix/libperfstat_aix.cpp index 79b8f09cc65..69f62245365 100644 --- a/src/hotspot/os/aix/libperfstat_aix.cpp +++ b/src/hotspot/os/aix/libperfstat_aix.cpp @@ -26,6 +26,7 @@ #include "libperfstat_aix.hpp" #include "misc_aix.hpp" +#include "runtime/os.hpp" #include @@ -71,11 +72,11 @@ static fun_perfstat_reset_t g_fun_perfstat_reset = nullptr; static fun_wpar_getcid_t g_fun_wpar_getcid = nullptr; bool libperfstat::init() { - - // Dynamically load the libperfstat porting library. - g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW); + const char* libperfstat = "/usr/lib/libperfstat.a(shr_64.o)"; + char ebuf[512]; + g_libhandle = os::dll_load(libperfstat, ebuf, sizeof(ebuf)); if (!g_libhandle) { - trcVerbose("Cannot load libperfstat.a (dlerror: %s)", dlerror()); + trcVerbose("Cannot load %s (error: %s)", libperfstat, ebuf); return false; } diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 8a7613055da..d09cbcd7a65 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1098,8 +1098,6 @@ bool os::dll_address_to_library_name(address addr, char* buf, return true; } -// Loads .dll/.so and in case of error it checks if .dll/.so was built -// for the same architecture as Hotspot is running on. void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { log_info(os)("attempting shared library load of %s", filename); @@ -1114,8 +1112,17 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { return nullptr; } - // RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants. - void * result= ::dlopen(filename, RTLD_LAZY); + // RTLD_LAZY has currently the same behavior as RTLD_NOW + // The dl is loaded immediately with all its dependants. + int dflags = RTLD_LAZY; + // check for filename ending with ')', it indicates we want to load + // a MEMBER module that is a member of an archive. + int flen = strlen(filename); + if (flen > 0 && filename[flen - 1] == ')') { + dflags |= RTLD_MEMBER; + } + + void * result= ::dlopen(filename, dflags); if (result != nullptr) { Events::log_dll_message(nullptr, "Loaded shared library %s", filename); // Reload dll cache. Don't do this in signal handling. -- cgit v1.2.3