diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-06-04 11:05:40 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-06-04 11:05:40 +0200 |
| commit | c6f6a9ef7249c63ad839fd0642df3a34e15bcf35 (patch) | |
| tree | 33f5bc2174d813f6aecf34af5275f185a6ed608c /src | |
| parent | 1c1e39ef644cda816e26f04ea63eb71919bb5942 (diff) | |
| download | box64-c6f6a9ef7249c63ad839fd0642df3a34e15bcf35.tar.gz box64-c6f6a9ef7249c63ad839fd0642df3a34e15bcf35.zip | |
Improved unloading of libs
Diffstat (limited to 'src')
| -rwxr-xr-x | src/librarian/librarian.c | 45 | ||||
| -rwxr-xr-x | src/librarian/library.c | 12 | ||||
| -rwxr-xr-x | src/tools/bridge.c | 2 |
3 files changed, 45 insertions, 14 deletions
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index 3273eeda..93344c9c 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -33,11 +33,12 @@ lib_t *NewLibrarian(box64context_t* context, int ownlibs) return maplib; } -static void freeLibraryRecurse(lib_t *maplib, x64emu_t *emu, int idx, char *freed) { +static void freeLibraryRecurse(lib_t *maplib, x64emu_t *emu, int idx, char *freed, library_t* owner) { if (freed[idx]) return; // Already freed freed[idx] = 1; // Avoid infinite loops library_t *lib = maplib->libraries[idx]; + if(lib==owner) return; // don't free owner of maplib printf_log(LOG_DEBUG, "Free %s\n", lib->name); for (int i = lib->depended.size - 1; i >= 0; --i) { int j; @@ -52,15 +53,15 @@ static void freeLibraryRecurse(lib_t *maplib, x64emu_t *emu, int idx, char *free printf_log(LOG_DEBUG, "Cyclic dependancy detected (cycle is between %s and %s)\n", lib->name, lib->depended.libs[i]->name); continue; } - freeLibraryRecurse(maplib, emu, j, freed); + freeLibraryRecurse(maplib, emu, j, freed, owner); if (freed[idx] != 1) { printf_log(LOG_DEBUG, "Library cleared (cyclic dependancy break)\n"); return; } } - library_t *oldptr = maplib->libraries[idx]; - Free1Library(&maplib->libraries[idx], emu); - maplib->libraries[idx] = oldptr; // Temporarily save the old address + library_t *ptr = maplib->libraries[idx]; + if(maplib->ownlibs) + Free1Library(&ptr, emu); freed[idx] = 2; } void FreeLibrarian(lib_t **maplib, x64emu_t *emu) @@ -68,18 +69,21 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu) if(!maplib || !*maplib) return; + library_t* owner = (*maplib)->owner; + (*maplib)->owner = NULL; // to avoid recursive free if((*maplib)->ownlibs && (*maplib)->libsz) { printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib); char *freed = (char*)calloc((*maplib)->libsz, sizeof(char)); if (!freed) { printf_log(LOG_INFO, "Failed to malloc freed table, using old algorithm (a crash is likely)\n"); - for (int i=(*maplib)->libsz-1; i>=0; --i) { - printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name); - Free1Library(&(*maplib)->libraries[i], emu); - } + for (int i=(*maplib)->libsz-1; i>=0; --i) + if((*maplib)->libraries[i]!=owner) { + printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name); + Free1Library(&(*maplib)->libraries[i], emu); + } } else { for (int i=(*maplib)->libsz-1; i>=0; --i) { - freeLibraryRecurse(*maplib, emu, i, freed); + freeLibraryRecurse(*maplib, emu, i, freed, owner); } memset((*maplib)->libraries, 0, (*maplib)->libsz*sizeof(library_t*)); // NULL = 0 anyway (*maplib)->libsz = 0; @@ -193,6 +197,23 @@ void MapLibRemoveLib(lib_t* maplib, library_t* lib) memmove(&maplib->libraries[idx], &maplib->libraries[idx+1], sizeof(library_t*)*(maplib->libsz-idx)); } +static void MapLibRemoveMapLib(lib_t* dest, lib_t* src) +{ + if(!src) + return; + //library_t *owner = src->owner; + for(int i=0; i<src->libsz; ++i) { + library_t* lib = src->libraries[i]; + if(!lib || !libraryInMapLib(dest, lib)) continue; + MapLibRemoveLib(dest, lib); + if(lib->maplib && src!=lib->maplib && dest!=lib->maplib) { + MapLibRemoveMapLib(dest, lib->maplib); + if(lib->maplib && src==my_context->local_maplib) + lib->maplib = NULL; + } + } +} + int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, const char* path, box64context_t* box64, x64emu_t* emu) { printf_log(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":""); @@ -216,6 +237,8 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib } if(!libraryInMapLib(maplib, lib)) MapLibAddLib(maplib, lib); + if(maplib->ownlibs) + MapLibRemoveMapLib(my_context->local_maplib, maplib); } } else { // promote lib from local to global... @@ -227,7 +250,7 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib } if(!libraryInMapLib(my_context->maplib, lib)) MapLibAddLib(my_context->maplib, lib); - MapLibRemoveLib(my_context->local_maplib, lib); + MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib); } add_neededlib(neededlibs, lib); if (lib && deplib) add_dependedlib(&lib->depended, deplib); diff --git a/src/librarian/library.c b/src/librarian/library.c index 4d2a1d22..1b858447 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -249,13 +249,17 @@ library_t *NewLibrary(const char* path, box64context_t* context) printf_log(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name); if(box64_nopulse) { if(strstr(lib->name, "libpulse.so")==lib->name || strstr(lib->name, "libpulse-simple.so")==lib->name) { - Free1Library(&lib, NULL); + free(lib->name); + free(lib->path); + free(lib); return NULL; } } if(box64_novulkan) { if(strstr(lib->name, "libvulkan.so")==lib->name) { - Free1Library(&lib, NULL); + free(lib->name); + free(lib->path); + free(lib); return NULL; } } @@ -273,7 +277,9 @@ library_t *NewLibrary(const char* path, box64context_t* context) // nothing loaded, so error... if(lib->type==-1) { - Free1Library(&lib, NULL); + free(lib->name); + free(lib->path); + free(lib); return NULL; } diff --git a/src/tools/bridge.c b/src/tools/bridge.c index 4bcdee0f..e05bb1a3 100755 --- a/src/tools/bridge.c +++ b/src/tools/bridge.c @@ -55,6 +55,8 @@ bridge_t *NewBridge() } void FreeBridge(bridge_t** bridge) { + if(!bridge || !*bridge) + return; brick_t *b = (*bridge)->head; while(b) { brick_t *n = b->next; |