From de6897e44c52138bc96623ac645e848c43953cbd Mon Sep 17 00:00:00 2001 From: JoKern65 Date: Mon, 8 Apr 2024 14:25:33 +0200 Subject: [PATCH 1/5] JDK-8329850 --- src/hotspot/os/aix/porting_aix.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index 68233097b4957..6108974549d30 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -906,10 +906,11 @@ struct TableLocker { ~TableLocker() { pthread_mutex_unlock(&g_handletable_mutex); } }; struct handletableentry{ - void* handle; - ino64_t inode; - dev64_t devid; - uint refcount; + void* handle; + ino64_t inode; + dev64_t devid; + unsigned long hash; + uint refcount; }; constexpr unsigned init_num_handles = 128; static unsigned max_handletable = 0; @@ -1049,6 +1050,16 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { return nullptr; } else { + // extract member string if exist and generate hash of it + unsigned long hash = 0; + const char* substr; + if (filename[strlen(filename) - 1] == ')' && (substr = strrchr(filename, '('))) { + // Mocklisp hash function. + while (*substr) { + hash = (hash << 5) - hash + (unsigned long)*substr++; + } + } + unsigned i = 0; TableLocker lock; // check if library belonging to filename is already loaded. @@ -1056,7 +1067,8 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { for (i = 0; i < g_handletable_used; i++) { if ((p_handletable + i)->handle && (p_handletable + i)->inode == libstat.st_ino && - (p_handletable + i)->devid == libstat.st_dev) { + (p_handletable + i)->devid == libstat.st_dev && + (p_handletable + i)->hash == hash) { (p_handletable + i)->refcount++; result = (p_handletable + i)->handle; break; @@ -1084,6 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { (p_handletable + i)->handle = result; (p_handletable + i)->inode = libstat.st_ino; (p_handletable + i)->devid = libstat.st_dev; + (p_handletable + i)->hash = hash; (p_handletable + i)->refcount = 1; } else { From 3ec79644d684ffa3724d4c1ca5f475fbe590bef6 Mon Sep 17 00:00:00 2001 From: JoKern65 Date: Thu, 25 Apr 2024 11:59:24 +0200 Subject: [PATCH 2/5] change from hash to allocated string --- src/hotspot/os/aix/porting_aix.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index 6108974549d30..94f9ad21ca16c 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -909,7 +909,7 @@ struct handletableentry{ void* handle; ino64_t inode; dev64_t devid; - unsigned long hash; + char* member; uint refcount; }; constexpr unsigned init_num_handles = 128; @@ -1050,14 +1050,12 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { return nullptr; } else { - // extract member string if exist and generate hash of it - unsigned long hash = 0; + // extract member string if exist duplicate it and store pointer of it + // if member does not exist store nullptr + char* member = nullptr; const char* substr; if (filename[strlen(filename) - 1] == ')' && (substr = strrchr(filename, '('))) { - // Mocklisp hash function. - while (*substr) { - hash = (hash << 5) - hash + (unsigned long)*substr++; - } + member = os::strdup(substr); } unsigned i = 0; @@ -1068,7 +1066,9 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { if ((p_handletable + i)->handle && (p_handletable + i)->inode == libstat.st_ino && (p_handletable + i)->devid == libstat.st_dev && - (p_handletable + i)->hash == hash) { + (((p_handletable + i)->member == nullptr && member == nullptr) || + ((p_handletable + i)->member != nullptr && member != nullptr && + strcmp((p_handletable + i)->member, member) == 0))) { (p_handletable + i)->refcount++; result = (p_handletable + i)->handle; break; @@ -1096,7 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { (p_handletable + i)->handle = result; (p_handletable + i)->inode = libstat.st_ino; (p_handletable + i)->devid = libstat.st_dev; - (p_handletable + i)->hash = hash; + (p_handletable + i)->member = member; (p_handletable + i)->refcount = 1; } else { @@ -1144,7 +1144,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { // while in the second case we simply have to nag. res = (0 == ::dlclose(libhandle)); if (!res) { - // error analysis when dlopen fails + // error analysis when dlclose fails const char* error_report = ::dlerror(); if (error_report == nullptr) { error_report = "dlerror returned no error description"; @@ -1158,7 +1158,10 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { if (i < g_handletable_used) { if (res) { // First case: libhandle was found (with refcount == 0) and ::dlclose successful, - // so delete entry from array + // so delete entry from array (do not forget to free member-string space if member exists) + if ((p_handletable + i)->member) { + os::free((p_handletable + i)->member); + } g_handletable_used--; // If the entry was the last one of the array, the previous g_handletable_used-- // is sufficient to remove the entry from the array, otherwise we move the last From b1ec5ed33d3812e38ee39d7828445f9a5c05d45a Mon Sep 17 00:00:00 2001 From: JoKern65 Date: Thu, 25 Apr 2024 12:33:56 +0200 Subject: [PATCH 3/5] cosmetic changes --- src/hotspot/os/aix/porting_aix.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index 94f9ad21ca16c..afd18e141655d 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -1066,7 +1066,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { if ((p_handletable + i)->handle && (p_handletable + i)->inode == libstat.st_ino && (p_handletable + i)->devid == libstat.st_dev && - (((p_handletable + i)->member == nullptr && member == nullptr) || + (((p_handletable + i)->member == member) || ((p_handletable + i)->member != nullptr && member != nullptr && strcmp((p_handletable + i)->member, member) == 0))) { (p_handletable + i)->refcount++; @@ -1159,8 +1159,8 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { if (res) { // First case: libhandle was found (with refcount == 0) and ::dlclose successful, // so delete entry from array (do not forget to free member-string space if member exists) - if ((p_handletable + i)->member) { - os::free((p_handletable + i)->member); + if ((p_handletable + i)->member) { + os::free((p_handletable + i)->member); } g_handletable_used--; // If the entry was the last one of the array, the previous g_handletable_used-- From 584502a84d057359da007a6b6224afb690814006 Mon Sep 17 00:00:00 2001 From: JoKern65 Date: Thu, 25 Apr 2024 16:32:13 +0200 Subject: [PATCH 4/5] Back to the roots --- src/hotspot/os/aix/porting_aix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index afd18e141655d..d3e91c0d776be 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -1066,7 +1066,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) { if ((p_handletable + i)->handle && (p_handletable + i)->inode == libstat.st_ino && (p_handletable + i)->devid == libstat.st_dev && - (((p_handletable + i)->member == member) || + (((p_handletable + i)->member == nullptr && member == nullptr) || ((p_handletable + i)->member != nullptr && member != nullptr && strcmp((p_handletable + i)->member, member) == 0))) { (p_handletable + i)->refcount++; From 97ad36701a384c7949703fc07da321d8eafd96f3 Mon Sep 17 00:00:00 2001 From: JoKern65 Date: Thu, 25 Apr 2024 16:40:18 +0200 Subject: [PATCH 5/5] set ptr to nullptr after free --- src/hotspot/os/aix/porting_aix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/os/aix/porting_aix.cpp b/src/hotspot/os/aix/porting_aix.cpp index d3e91c0d776be..630bdf22c4473 100644 --- a/src/hotspot/os/aix/porting_aix.cpp +++ b/src/hotspot/os/aix/porting_aix.cpp @@ -1161,6 +1161,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { // so delete entry from array (do not forget to free member-string space if member exists) if ((p_handletable + i)->member) { os::free((p_handletable + i)->member); + (p_handletable + i)->member = nullptr; } g_handletable_used--; // If the entry was the last one of the array, the previous g_handletable_used--