From 14e20e643515d4e7171f54e6d2fb78cf784f7d10 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Fri, 28 Apr 2023 17:13:37 +0200 Subject: Fix for local library open using dlopen that are then promoted to global with another dlopen (help java 17, probably other too) --- src/include/librarian.h | 2 ++ src/librarian/librarian.c | 29 ++++++++++++++++++++++------- src/wrapped/wrappedlibdl.c | 2 ++ 3 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/include/librarian.h b/src/include/librarian.h index 2ff059df..6219f00c 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -25,6 +25,8 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu); library_t* GetLibMapLib(lib_t* maplib, const char* name); library_t* GetLibInternal(const char* name); +void promoteLocalLibGlobal(library_t* lib); +int isLibLocal(library_t* lib); uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername); int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver); int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver); diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index e480f907..d9f20a9a 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -156,6 +156,27 @@ static void MapLibRemoveMapLib(lib_t* dest, lib_t* src) } } +void promoteLocalLibGlobal(library_t* lib) +{ + if(!lib || !my_context) + return; + // promote lib from local to global... + // for add the depending local libs... + if(lib->maplib) { + MapLibAddMapLib(my_context->maplib, lib, lib->maplib); + } + if(!libraryInMapLib(my_context->maplib, lib)) + MapLibAddLib(my_context->maplib, lib); + MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib); +} + +int isLibLocal(library_t* lib) +{ + if(!lib || !my_context) + return 0; + return libraryInMapLib(my_context->local_maplib, lib); +} + int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int n, box64context_t* box64, x64emu_t* emu) { const char* path = needed->names[n]; @@ -187,13 +208,7 @@ int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int n, box } } else { // promote lib from local to global... - // for add the depending local libs... - if(lib->maplib) { - MapLibAddMapLib(my_context->maplib, lib, lib->maplib); - } - if(!libraryInMapLib(my_context->maplib, lib)) - MapLibAddLib(my_context->maplib, lib); - MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib); + promoteLocalLibGlobal(lib); } return 0; } diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 9caaba56..350eb088 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -139,6 +139,8 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag) } IncRefCount(dl->dllibs[i].lib, emu); ++dl->dllibs[i].count; + if(!is_local && isLibLocal(dl->dllibs[i].lib)) + promoteLocalLibGlobal(dl->dllibs[i].lib); printf_dlsym(LOG_DEBUG, "dlopen: Recycling %s/%p count=%ld (dlopened=%ld, elf_index=%d)\n", rfilename, (void*)(i+1), dl->dllibs[i].count, dl->dllibs[i].dlopened, GetElfIndex(dl->dllibs[i].lib)); return (void*)(i+1); } -- cgit 1.4.1