mirror of
https://github.com/ptitSeb/box86.git
synced 2025-05-08 21:08:57 +08:00
[ELFLOADER] Improved handling of dlopen local lib (helps Half-Life, Garry's Mod, and probably many other)
This commit is contained in:
parent
7ae3200c6f
commit
399b2c7f8a
@ -872,20 +872,25 @@ add_test(NAME idiv COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref20.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
|
||||
add_test(NAME multiple_dlopen COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test21 -D TEST_OUTPUT=tmpfile21.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref21.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
|
||||
foreach(file ${extension_tests})
|
||||
get_filename_component(testname "${file}" NAME_WE)
|
||||
add_test(NAME "${testname}" COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/extensions/${testname} -D TEST_OUTPUT=tmpfile-${testname}.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/extensions/${testname}.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake)
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
add_test(NAME sse_optimized COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test17_o2 -D TEST_OUTPUT=tmpfile17_o2.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref17_o2.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
set_tests_properties(sse_optimized PROPERTIES ENVIRONMENT "BOX86_DYNAREC_FASTNAN=0;BOX86_DYNAREC_FASTROUND=0")
|
||||
set_tests_properties(sse_optimized PROPERTIES ENVIRONMENT "BOX86_DYNAREC_FASTNAN=0;BOX86_DYNAREC_FASTROUND=0")
|
||||
|
||||
endif(BOX86LIB)
|
||||
|
@ -59,6 +59,7 @@ typedef struct needed_libs_s {
|
||||
int size;
|
||||
char** names;
|
||||
library_t** libs;
|
||||
int nb_done;
|
||||
} needed_libs_t;
|
||||
|
||||
void free_neededlib(needed_libs_t* needed);
|
||||
|
@ -37,6 +37,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
|
||||
int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, const char* defver);
|
||||
|
||||
void MapLibRemoveLib(lib_t* maplib, library_t* lib);
|
||||
void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref);
|
||||
|
||||
const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, const char* symname);
|
||||
|
||||
|
@ -41,7 +41,7 @@ void FreeLibrarian(lib_t **maplib, x86emu_t *emu)
|
||||
|
||||
/*if((*maplib)->ownlibs && (*maplib)->libsz) {
|
||||
for(int i=0; i<(*maplib)->libsz; ++i) {
|
||||
printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
|
||||
printf_dump(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
|
||||
DecRefCount(&(*maplib)->libraries[i], emu);
|
||||
}
|
||||
}*/
|
||||
@ -105,6 +105,28 @@ void MapLibAddLib(lib_t* maplib, library_t* lib)
|
||||
++maplib->libsz;
|
||||
}
|
||||
|
||||
void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref)
|
||||
{
|
||||
if(libraryInMapLib(maplib, lib))
|
||||
return;
|
||||
if (maplib->libsz == maplib->libcap) {
|
||||
maplib->libcap += 8;
|
||||
maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
|
||||
}
|
||||
// find insersion point
|
||||
int point = ref?maplib->libsz:0;
|
||||
if(ref)
|
||||
for(int i=0; i<maplib->libsz; ++i)
|
||||
if(maplib->libraries[i]==ref) {
|
||||
point = i;
|
||||
i = maplib->libsz;
|
||||
}
|
||||
if(point<maplib->libsz)
|
||||
memmove(&maplib->libraries[point+1], &maplib->libraries[point], sizeof(library_t*)*(maplib->libsz-point));
|
||||
maplib->libraries[point] = lib;
|
||||
++maplib->libsz;
|
||||
}
|
||||
|
||||
static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src)
|
||||
{
|
||||
if(!src)
|
||||
@ -180,29 +202,26 @@ int isLibLocal(library_t* lib)
|
||||
static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int n, elfheader_t* verneeded, box86context_t* box86, x86emu_t* emu)
|
||||
{
|
||||
const char* path = needed->names[n];
|
||||
printf_log(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":"");
|
||||
printf_dump(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":"");
|
||||
// first check if lib is already loaded
|
||||
library_t *lib = getLib(my_context->maplib, path);
|
||||
if(lib) {
|
||||
IncRefCount(lib, emu); // increment cntref
|
||||
needed->libs[n] = lib;
|
||||
printf_log(LOG_DEBUG, "Already present in maplib => success\n");
|
||||
printf_dump(LOG_DEBUG, "Already present in maplib => success\n");
|
||||
return 0;
|
||||
}
|
||||
// check also in the local loaded lib
|
||||
lib = getLib(my_context->local_maplib, path);
|
||||
if(lib) {
|
||||
printf_log(LOG_DEBUG, "Already present in local_maplib => success\n");
|
||||
printf_dump(LOG_DEBUG, "Already present in local_maplib => success\n");
|
||||
needed->libs[n] = lib;
|
||||
IncRefCount(lib, emu); // increment cntref
|
||||
if(local) {
|
||||
// add lib to maplib...
|
||||
if(maplib) {
|
||||
if(lib->maplib) {
|
||||
MapLibAddMapLib(maplib, lib, lib->maplib);
|
||||
}
|
||||
if(!libraryInMapLib(maplib, lib))
|
||||
MapLibAddLib(maplib, lib);
|
||||
MapLibPrependLib(maplib, lib, NULL); // todo: Also insert libs needed by lib, after lib? But current lib->maplib is probably not the solution
|
||||
if(maplib->ownlibs)
|
||||
MapLibRemoveMapLib(my_context->local_maplib, maplib);
|
||||
}
|
||||
@ -215,7 +234,7 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
|
||||
// load a new one
|
||||
needed->libs[n] = lib = NewLibrary(path, box86, verneeded);
|
||||
if(!lib) {
|
||||
printf_log(LOG_DEBUG, "Faillure to create lib => fail\n");
|
||||
printf_dump(LOG_DEBUG, "Faillure to create lib => fail\n");
|
||||
return 1; //Error
|
||||
}
|
||||
|
||||
@ -224,8 +243,6 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
|
||||
MapLibAddLib(my_context->local_maplib, lib);
|
||||
if(maplib) {
|
||||
MapLibAddLib(maplib, lib);
|
||||
if(!lib->maplib)
|
||||
lib->maplib = maplib;
|
||||
} else {
|
||||
lib->maplib = NewLibrarian(box86, 0);
|
||||
MapLibAddLib(lib->maplib, lib);
|
||||
@ -238,7 +255,7 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
|
||||
maplib = (local)?lib->maplib:my_context->maplib;
|
||||
|
||||
if(AddSymbolsLibrary(maplib, lib, emu)) { // also add needed libs
|
||||
printf_log(LOG_DEBUG, "Failure to Add lib => fail\n");
|
||||
printf_dump(LOG_DEBUG, "Failure to Add lib => fail\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -247,7 +264,7 @@ static int AddNeededLib_add(lib_t* maplib, int local, needed_libs_t* needed, int
|
||||
linkmap_t *lm = addLinkMapLib(lib);
|
||||
if(!lm) {
|
||||
// Crashed already
|
||||
printf_log(LOG_DEBUG, "Failure to add lib linkmap\n");
|
||||
printf_dump(LOG_DEBUG, "Failure to add lib linkmap\n");
|
||||
return 1;
|
||||
}
|
||||
lm->l_addr = (Elf32_Addr)GetElfDelta(lib->e.elf);
|
||||
@ -271,8 +288,8 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
|
||||
} else {
|
||||
// it's an emulated lib,
|
||||
// load dependancies and launch init sequence
|
||||
if(LoadNeededLibs(mainelf, maplib, 0, bindnow, box86, emu)) {
|
||||
printf_log(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
|
||||
if(LoadNeededLibs(mainelf, maplib, local, bindnow, box86, emu)) {
|
||||
printf_dump(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
|
||||
return 1;
|
||||
}
|
||||
// some special case, where dependancies may not be correct
|
||||
@ -297,12 +314,12 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
|
||||
|
||||
// finalize the lib
|
||||
if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, emu)) {
|
||||
printf_log(LOG_DEBUG, "Failure to finalizing lib => fail\n");
|
||||
printf_dump(LOG_DEBUG, "Failure to finalizing lib => fail\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// success
|
||||
printf_log(LOG_DEBUG, "Created lib and added to maplib => success\n");
|
||||
printf_dump(LOG_DEBUG, "Created lib and added to maplib => success\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -351,20 +368,20 @@ void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box86conte
|
||||
return;
|
||||
for(int i=0; i<needed->size; ++i) {
|
||||
if(box86_log>=LOG_DEBUG && needed->libs[i])
|
||||
printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
|
||||
printf_dump(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
|
||||
AddNeededLib_remove(maplib, local, &needed->libs[i], box86, emu);
|
||||
}
|
||||
}
|
||||
|
||||
library_t* GetLibMapLib(lib_t* maplib, const char* name)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
|
||||
printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
|
||||
return getLib(maplib, name);
|
||||
}
|
||||
|
||||
library_t* GetLibInternal(const char* name)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
|
||||
printf_dump(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name);
|
||||
library_t* lib = getLib(my_context->maplib, name);
|
||||
if(!lib) lib = getLib(my_context->local_maplib, name);
|
||||
return lib;
|
||||
@ -388,6 +405,20 @@ static int isLocal(elfheader_t* self, library_t* l)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void CheckNeededLibs(needed_libs_t* needed)
|
||||
{
|
||||
while(needed->nb_done<needed->size) {
|
||||
library_t* lib = needed->libs[needed->nb_done++];
|
||||
if(lib) {
|
||||
int n = GetNeededLibsN(lib);
|
||||
char** names = GetNeededLibsNames(lib);
|
||||
for (int i=0; i<n; ++i) {
|
||||
add1lib_neededlib(needed, GetNeededLib(lib, i), names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
assert(self); // need self for this one
|
||||
@ -450,13 +481,17 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
|
||||
if(my_context->preload)
|
||||
for(int i=0; i<my_context->preload->size; ++i)
|
||||
if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver))
|
||||
if(*start)
|
||||
if(*start) {
|
||||
return 1;
|
||||
}
|
||||
// search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
|
||||
if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
|
||||
if(*start)
|
||||
if(*start) {
|
||||
return 1;
|
||||
// TODO: create a temporary map to search lib only 1 time, and in order of needed...
|
||||
}
|
||||
// This kind-of create a map to search lib only 1 time, and in order of needed...
|
||||
if(my_context->neededlibs)
|
||||
CheckNeededLibs(my_context->neededlibs);
|
||||
// search in needed libs from neededlibs first, in order
|
||||
if(my_context->neededlibs)
|
||||
for(int i=0; i<my_context->neededlibs->size; ++i)
|
||||
@ -468,8 +503,9 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
|
||||
if(maplib) {
|
||||
if(self && self!=my_context->elfs[0] && self!=(void*)1)
|
||||
if(GetSymbolStartEnd(GetMapSymbols(self), name, start, end, version, vername, 1, globdefver))
|
||||
if(*start)
|
||||
if(*start) {
|
||||
return 1;
|
||||
}
|
||||
for(int i=0; i<maplib->libsz; ++i) {
|
||||
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver))
|
||||
if(*start) {
|
||||
@ -482,8 +518,17 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
|
||||
int ok = 0;
|
||||
// GetSymbolStartEnd should not change start/end if symbol is not found
|
||||
if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, weakdefver))
|
||||
if(*start)
|
||||
if(*start) {
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
// search in needed libs from neededlibs first, in order
|
||||
if(my_context->neededlibs)
|
||||
for(int i=0; i<my_context->neededlibs->size; ++i)
|
||||
if(GetLibWeakSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), weakdefver))
|
||||
if(*start) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(int i=0; i<maplib->libsz; ++i) {
|
||||
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver))
|
||||
@ -542,7 +587,9 @@ static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name,
|
||||
if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
|
||||
if(*start)
|
||||
return 1;
|
||||
// TODO: create a temporary map to search lib only 1 time, and in order of needed...
|
||||
// This kind-of create a map to search lib only 1 time, and in order of needed...
|
||||
if(my_context->neededlibs)
|
||||
CheckNeededLibs(my_context->neededlibs);
|
||||
// search in needed libs from neededlibs first, in order
|
||||
if(my_context->neededlibs)
|
||||
for(int i=0; i<my_context->neededlibs->size; ++i)
|
||||
|
@ -209,7 +209,7 @@ static void initWrappedLib(library_t *lib, box86context_t* context) {
|
||||
printf_log(LOG_NONE, "Error initializing native %s (last dlerror is %s)\n", lib->name, error_str);
|
||||
return; // non blocker...
|
||||
}
|
||||
printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
|
||||
printf_dump(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
|
||||
lib->fini = wrappedlibs[i].fini;
|
||||
lib->getglobal = WrappedLib_GetGlobal;
|
||||
lib->getweak = WrappedLib_GetWeak;
|
||||
@ -225,13 +225,13 @@ static void initWrappedLib(library_t *lib, box86context_t* context) {
|
||||
linkmap_t *lm = addLinkMapLib(lib);
|
||||
if(!lm) {
|
||||
// Crashed already
|
||||
printf_log(LOG_DEBUG, "Failure to add lib %s linkmap\n", lib->name);
|
||||
printf_dump(LOG_DEBUG, "Failure to add lib %s linkmap\n", lib->name);
|
||||
break;
|
||||
}
|
||||
struct link_map real_lm;
|
||||
#ifndef ANDROID
|
||||
if(dlinfo(lib->w.lib, RTLD_DI_LINKMAP, &real_lm)) {
|
||||
printf_log(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
|
||||
printf_dump(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
|
||||
}
|
||||
#endif
|
||||
lm->l_addr = real_lm.l_addr;
|
||||
@ -253,7 +253,7 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box86context_t*
|
||||
}
|
||||
elfheader_t *elf_header = LoadAndCheckElfHeader(f, libname, 0);
|
||||
if(!elf_header) {
|
||||
printf_log(LOG_DEBUG, "Error: reading elf header of %s\n", libname); // this one can be too alarming...
|
||||
printf_dump(LOG_DEBUG, "Error: reading elf header of %s\n", libname); // this one can be too alarming...
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
@ -304,21 +304,21 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box86context_t*
|
||||
lib->path = box_strdup(libname);
|
||||
}
|
||||
|
||||
printf_log(LOG_INFO, "Using emulated %s\n", libname);
|
||||
printf_dump(LOG_INFO, "Using emulated %s\n", libname);
|
||||
#ifdef DYNAREC
|
||||
if(libname && box86_dynarec_bleeding_edge && strstr(libname, "libmonobdwgc-2.0.so")) {
|
||||
printf_log(LOG_INFO, "MonoBleedingEdge detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
|
||||
printf_dump(LOG_INFO, "MonoBleedingEdge detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
|
||||
box86_dynarec_bigblock = 0;
|
||||
box86_dynarec_strongmem = 1;
|
||||
}
|
||||
if(libname && box86_dynarec_jvm && strstr(libname, "libjvm.so")) {
|
||||
printf_log(LOG_INFO, "libjvm detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
|
||||
printf_dump(LOG_INFO, "libjvm detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
|
||||
box86_dynarec_bigblock = 0;
|
||||
box86_dynarec_strongmem = 1;
|
||||
}
|
||||
#endif
|
||||
if(libname && box86_libcef && strstr(libname, "libcef.so")) {
|
||||
printf_log(LOG_INFO, "libcef detected, using malloc_hack_2\n");
|
||||
printf_dump(LOG_INFO, "libcef detected, using malloc_hack_2\n");
|
||||
box86_malloc_hack = 2;
|
||||
}
|
||||
return 1;
|
||||
@ -372,7 +372,7 @@ static int isEssentialLib(const char* name) {
|
||||
|
||||
library_t *NewLibrary(const char* path, box86context_t* context, elfheader_t* verneeded)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Trying to load \"%s\"\n", path);
|
||||
printf_dump(LOG_DEBUG, "Trying to load \"%s\"\n", path);
|
||||
library_t *lib = (library_t*)box_calloc(1, sizeof(library_t));
|
||||
lib->path = box_realpath(path, NULL);
|
||||
if(!lib->path)
|
||||
@ -383,7 +383,7 @@ library_t *NewLibrary(const char* path, box86context_t* context, elfheader_t* ve
|
||||
lib->name = Path2Name(path);
|
||||
lib->nbdot = NbDot(lib->name);
|
||||
lib->type = LIB_UNNKNOW;
|
||||
printf_log(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name);
|
||||
printf_dump(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name);
|
||||
if(box86_nopulse) {
|
||||
if(strstr(lib->name, "libpulse.so")==lib->name || strstr(lib->name, "libpulse-simple.so")==lib->name) {
|
||||
box_free(lib->name);
|
||||
@ -468,12 +468,12 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x86emu_t*
|
||||
int weak;
|
||||
if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL, NULL, NULL)) {
|
||||
SetTraceEmu(trace_start, trace_end);
|
||||
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
|
||||
printf_dump(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
|
||||
box_free(trace_func);
|
||||
trace_func = NULL;
|
||||
} else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, -1, NULL, 0, NULL)) {
|
||||
SetTraceEmu(trace_start, trace_end);
|
||||
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
|
||||
printf_dump(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
|
||||
box_free(trace_func);
|
||||
trace_func = NULL;
|
||||
}
|
||||
@ -502,7 +502,7 @@ void Free1Library(library_t **the_lib, x86emu_t* emu)
|
||||
|
||||
library_t* lib = *the_lib;
|
||||
|
||||
printf_log(LOG_DEBUG, "Free1Library %s\n", lib->name);
|
||||
printf_dump(LOG_DEBUG, "Free1Library %s\n", lib->name);
|
||||
// remove lib from maplib/local_maplib...
|
||||
if(my_context) {
|
||||
MapLibRemoveLib(my_context->maplib, lib);
|
||||
@ -611,7 +611,7 @@ int IsSameLib(library_t* lib, const char* path)
|
||||
}
|
||||
int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver)
|
||||
{
|
||||
if(!name[0])
|
||||
if(!lib || !name[0])
|
||||
return 0;
|
||||
khint_t k;
|
||||
// get a new symbol
|
||||
@ -823,7 +823,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
|
||||
symbol = GetNativeSymbolUnversioned(lib->w.lib, newname);
|
||||
}
|
||||
if(!symbol) {
|
||||
printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
|
||||
printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
|
||||
return 0;
|
||||
}
|
||||
s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
|
||||
@ -879,7 +879,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
|
||||
symbol = GetNativeSymbolUnversioned(lib->w.lib, newname);
|
||||
}
|
||||
if(!symbol) {
|
||||
printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
|
||||
printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", name, lib->name);
|
||||
return 0;
|
||||
}
|
||||
s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
|
||||
@ -904,7 +904,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
|
||||
if(!symbol)
|
||||
symbol = GetNativeSymbolUnversioned(lib->w.lib, kh_value(lib->w.symbol2map, k).name);
|
||||
if(!symbol) {
|
||||
printf_log(LOG_INFO, "Warning, function %s not found in lib %s\n", kh_value(lib->w.symbol2map, k).name, lib->name);
|
||||
printf_dump(LOG_INFO, "Warning, function %s not found in lib %s\n", kh_value(lib->w.symbol2map, k).name, lib->name);
|
||||
return 0;
|
||||
}
|
||||
s->addr = AddBridge(lib->w.bridge, s->w, symbol, 0, name);
|
||||
@ -939,7 +939,7 @@ int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *add
|
||||
int GetNeededLibsN(library_t* lib) {
|
||||
switch (lib->type) {
|
||||
case LIB_WRAPPED: return lib->w.needed?lib->w.needed->size:0;
|
||||
case LIB_EMULATED: return lib->e.elf->needed->size;
|
||||
case LIB_EMULATED: return lib->e.elf->needed?lib->e.elf->needed->size:0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -957,11 +957,11 @@ library_t* GetNeededLib(library_t* lib, int idx)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char** GetNeededLibs(library_t* lib)
|
||||
char** GetNeededLibsNames(library_t* lib)
|
||||
{
|
||||
switch (lib->type) {
|
||||
case LIB_WRAPPED: return lib->w.needed?lib->w.needed->names:NULL;
|
||||
case LIB_EMULATED: return lib->e.elf->needed->names;
|
||||
case LIB_EMULATED: return lib->e.elf->needed?lib->e.elf->needed->names:NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1078,7 +1078,7 @@ void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name)
|
||||
// add it
|
||||
if(needed->size+1<=needed->cap)
|
||||
return;
|
||||
needed->cap = needed->size+1;
|
||||
needed->cap = needed->size+4;
|
||||
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;
|
||||
|
1
tests/ref21.txt
Normal file
1
tests/ref21.txt
Normal file
@ -0,0 +1 @@
|
||||
2/1
|
BIN
tests/test21
Executable file
BIN
tests/test21
Executable file
Binary file not shown.
41
tests/test21.c
Normal file
41
tests/test21.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Compile with (on x86_64 archs):
|
||||
* gcc -m32 -DV1 -shared -o test21_v1.so test21.c
|
||||
* gcc -m32 -DV2 -shared -o test21_v2.so test21.c
|
||||
* gcc -m32 -o test21 test21.c -ldl -Wl,-z,origin,-rpath='$ORIGIN'
|
||||
*/
|
||||
|
||||
#if defined(V1)
|
||||
int __attribute__((noinline)) getVersion() { asm(""); return 1; }
|
||||
int acquireVersion() { return getVersion(); }
|
||||
|
||||
#elif defined(V2)
|
||||
int __attribute__((noinline)) getVersion() { asm(""); return 2; }
|
||||
int returnVersion() { return getVersion(); }
|
||||
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef int(*iFv_t)(void);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
void* v1 = dlopen("test21_v1.so", RTLD_NOW);
|
||||
void* v2 = dlopen("test21_v2.so", RTLD_NOW);
|
||||
if(!v1 || !v2) {
|
||||
printf("Error openning libs: v1=%p, v2=%p\n", v1, v2);
|
||||
exit(-1);
|
||||
}
|
||||
iFv_t returnVersion = (iFv_t)dlsym(v2, "returnVersion");
|
||||
iFv_t acquireVersion = (iFv_t)dlsym(v1, "acquireVersion");
|
||||
if(!returnVersion || !acquireVersion) {
|
||||
printf("Error getting symbol return=%p/acquire=%p\n", returnVersion, acquireVersion);
|
||||
exit(-2);
|
||||
}
|
||||
printf("%d/%d\n", returnVersion(), acquireVersion()); return 0;
|
||||
dlclose(v2);
|
||||
dlclose(v1);
|
||||
}
|
||||
|
||||
#endif
|
BIN
tests/test21_v1.so
Executable file
BIN
tests/test21_v1.so
Executable file
Binary file not shown.
BIN
tests/test21_v2.so
Executable file
BIN
tests/test21_v2.so
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user