From 23fe2ece586d3ed750e905e1b71a2cd1da91f335 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Thu, 10 Aug 2023 12:06:43 +0000 Subject: [PATCH] 8313616: support loading library members on AIX in os::dll_load Reviewed-by: mdoerr --- 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 e657431f125..98b689d4530 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1101,8 +1101,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); @@ -1122,8 +1120,17 @@ void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { event.set_name(filename); #endif - // 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.