diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/include/box64context.h | 1 | ||||
| -rwxr-xr-x | src/include/librarian.h | 1 | ||||
| -rwxr-xr-x | src/librarian/librarian.c | 23 | ||||
| -rwxr-xr-x | src/librarian/library.c | 24 | ||||
| -rwxr-xr-x | src/main.c | 19 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 12 |
6 files changed, 53 insertions, 27 deletions
diff --git a/src/include/box64context.h b/src/include/box64context.h index 2c0063e2..3fe285dc 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -59,6 +59,7 @@ void free_neededlib(needed_libs_t* needed); needed_libs_t* new_neededlib(int n); needed_libs_t* copy_neededlib(needed_libs_t* needed); void add1_neededlib(needed_libs_t* needed); +void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name); typedef struct base_segment_s { uintptr_t base; diff --git a/src/include/librarian.h b/src/include/librarian.h index b7a46880..2ff059df 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -22,6 +22,7 @@ void FreeDLPrivate(dlprivate_t **lib); box64context_t* GetLibrarianContext(lib_t* maplib); kh_mapsymbols_t* GetGlobalData(lib_t* maplib); int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error +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); uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername); diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index 6733c3af..e480f907 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -318,11 +318,6 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b } // error while loadind lib, unload... if(ret) { - for(int i=0; i<needed->size; ++i) { - if(box64_log>=LOG_DEBUG && needed->libs[i]) - printf_log(LOG_DEBUG, "Will decref after failed load %s\n", needed->names[i]); - AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu); - } return ret; } // add dependant libs and init them @@ -332,15 +327,19 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b if(!allow_missing_libs) ret = 1; } // error while loadind lib, unload... - if(ret) { - for(int i=0; i<needed->size; ++i) { - if(box64_log>=LOG_DEBUG && needed->libs[i]) - printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]); - AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu); - } - } return ret; } +EXPORTDYN +void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu) +{ + if(!needed) // no needed libs, no problems + return; + for(int i=0; i<needed->size; ++i) { + if(box64_log>=LOG_DEBUG && needed->libs[i]) + printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]); + AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu); + } +} library_t* GetLibMapLib(lib_t* maplib, const char* name) { diff --git a/src/librarian/library.c b/src/librarian/library.c index 9652fe7e..4c7995a7 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -1047,6 +1047,24 @@ void add1_neededlib(needed_libs_t* needed) needed->names = (char**)realloc(needed->names, needed->cap*sizeof(char*)); needed->size++; } +void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name) +{ + if(!needed || !lib) + return; + // check if lib is already present + for (int i=0; i<needed->size; ++i) + if(needed->libs[i]==lib) + return; + // add it + if(needed->size+1<=needed->cap) + return; + needed->cap = needed->size+1; + needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*)); + needed->names = (char**)realloc(needed->names, needed->cap*sizeof(char*)); + needed->libs[needed->size] = lib; + needed->names[needed->size] = name; + needed->size++; +} needed_libs_t* copy_neededlib(needed_libs_t* needed) { if(!needed) @@ -1098,8 +1116,10 @@ int DecRefCount(library_t** lib, x64emu_t* emu) { if(!lib || !*lib) return 1; - if((*lib)->type==LIB_UNNKNOW) - return 1; + if((*lib)->type==LIB_UNNKNOW) { + Free1Library(lib, emu); + return 0; + } int ret = 1; needed_libs_t* needed = NULL; int freed = 0; diff --git a/src/main.c b/src/main.c index b942f978..a8b0cff3 100755 --- a/src/main.c +++ b/src/main.c @@ -1701,12 +1701,19 @@ int main(int argc, const char **argv, char **env) { AddMainElfToLinkmap(elf_header); // pre-load lib if needed if(ld_preload.size) { - my_context->preload = new_neededlib(ld_preload.size); - for(int i=0; i<ld_preload.size; ++i) - my_context->preload->names[i] = ld_preload.paths[i]; - if(AddNeededLib(my_context->maplib, 0, 0, my_context->preload, my_context, emu)) { - printf_log(LOG_INFO, "Warning, cannot pre-load of the libs\n"); - } + my_context->preload = new_neededlib(0); + for(int i=0; i<ld_preload.size; ++i) { + needed_libs_t* tmp = new_neededlib(1); + tmp->names[0] = ld_preload.paths[i]; + if(AddNeededLib(my_context->maplib, 0, 0, tmp, my_context, emu)) { + printf_log(LOG_INFO, "Warning, cannot pre-load of %s\n", tmp->names[0]); + RemoveNeededLib(my_context->maplib, 0, tmp, my_context, emu); + } else { + for(int j=0; j<tmp->size; ++j) + add1lib_neededlib(my_context->preload, tmp->libs[j], tmp->names[j]); + free_neededlib(tmp); + } + } } FreeCollection(&ld_preload); // Call librarian to load all dependant elf diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 9267ee4b..34df9340 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -173,19 +173,17 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag) // Then open the lib my_context->deferredInit = 1; int bindnow = (!box64_musl && (flag&0x2))?1:0; - needed_libs_t tmp = {0}; - char* names[] = {rfilename}; - library_t* libs[] = { NULL }; - tmp.size = tmp.cap = 1; - tmp.names = names; - tmp.libs = libs; - if(AddNeededLib(NULL, is_local, bindnow, &tmp, my_context, emu)) { + needed_libs_t *tmp = new_neededlib(1); + tmp->names[0] = rfilename; + if(AddNeededLib(NULL, is_local, bindnow, tmp, my_context, emu)) { printf_dlsym(strchr(rfilename,'/')?LOG_DEBUG:LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag); if(!dl->last_error) dl->last_error = box_malloc(129); snprintf(dl->last_error, 129, "Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag); + RemoveNeededLib(NULL, is_local, tmp, my_context, emu); return NULL; } + free_neededlib(tmp); lib = GetLibInternal(rfilename); RunDeferredElfInit(emu); } else { |