Skip to content

Commit d459ae9

Browse files
Joachim KernGoeLin
authored andcommitted
8329850: [AIX] Allow loading of different members of same shared library archive
Backport-of: cfd19f017681a7aded67937c5132263bbcc7be6f
1 parent 835d016 commit d459ae9

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

src/hotspot/os/aix/porting_aix.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -906,10 +906,11 @@ struct TableLocker {
906906
~TableLocker() { pthread_mutex_unlock(&g_handletable_mutex); }
907907
};
908908
struct handletableentry{
909-
void* handle;
910-
ino64_t inode;
911-
dev64_t devid;
912-
uint refcount;
909+
void* handle;
910+
ino64_t inode;
911+
dev64_t devid;
912+
char* member;
913+
uint refcount;
913914
};
914915
constexpr unsigned init_num_handles = 128;
915916
static unsigned max_handletable = 0;
@@ -1049,14 +1050,25 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
10491050
return nullptr;
10501051
}
10511052
else {
1053+
// extract member string if exist duplicate it and store pointer of it
1054+
// if member does not exist store nullptr
1055+
char* member = nullptr;
1056+
const char* substr;
1057+
if (filename[strlen(filename) - 1] == ')' && (substr = strrchr(filename, '('))) {
1058+
member = os::strdup(substr);
1059+
}
1060+
10521061
unsigned i = 0;
10531062
TableLocker lock;
10541063
// check if library belonging to filename is already loaded.
10551064
// If yes use stored handle from previous ::dlopen() and increase refcount
10561065
for (i = 0; i < g_handletable_used; i++) {
10571066
if ((p_handletable + i)->handle &&
10581067
(p_handletable + i)->inode == libstat.st_ino &&
1059-
(p_handletable + i)->devid == libstat.st_dev) {
1068+
(p_handletable + i)->devid == libstat.st_dev &&
1069+
(((p_handletable + i)->member == nullptr && member == nullptr) ||
1070+
((p_handletable + i)->member != nullptr && member != nullptr &&
1071+
strcmp((p_handletable + i)->member, member) == 0))) {
10601072
(p_handletable + i)->refcount++;
10611073
result = (p_handletable + i)->handle;
10621074
break;
@@ -1084,6 +1096,7 @@ void* Aix_dlopen(const char* filename, int Flags, const char** error_report) {
10841096
(p_handletable + i)->handle = result;
10851097
(p_handletable + i)->inode = libstat.st_ino;
10861098
(p_handletable + i)->devid = libstat.st_dev;
1099+
(p_handletable + i)->member = member;
10871100
(p_handletable + i)->refcount = 1;
10881101
}
10891102
else {
@@ -1131,7 +1144,7 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
11311144
// while in the second case we simply have to nag.
11321145
res = (0 == ::dlclose(libhandle));
11331146
if (!res) {
1134-
// error analysis when dlopen fails
1147+
// error analysis when dlclose fails
11351148
const char* error_report = ::dlerror();
11361149
if (error_report == nullptr) {
11371150
error_report = "dlerror returned no error description";
@@ -1145,7 +1158,11 @@ bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) {
11451158
if (i < g_handletable_used) {
11461159
if (res) {
11471160
// First case: libhandle was found (with refcount == 0) and ::dlclose successful,
1148-
// so delete entry from array
1161+
// so delete entry from array (do not forget to free member-string space if member exists)
1162+
if ((p_handletable + i)->member) {
1163+
os::free((p_handletable + i)->member);
1164+
(p_handletable + i)->member = nullptr;
1165+
}
11491166
g_handletable_used--;
11501167
// If the entry was the last one of the array, the previous g_handletable_used--
11511168
// is sufficient to remove the entry from the array, otherwise we move the last

0 commit comments

Comments
 (0)