diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-05 15:09:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-05 15:09:11 +0100 |
| commit | f9bc94bfb8529c6b10c989ad3a355498a72d7f85 (patch) | |
| tree | 0925bfbe5acffb73cff63fbc54724ecd9937cbe8 /src | |
| parent | 72119ddfa449bdfc98c7152653047f34feca332c (diff) | |
| download | box64-f9bc94bfb8529c6b10c989ad3a355498a72d7f85.tar.gz box64-f9bc94bfb8529c6b10c989ad3a355498a72d7f85.zip | |
Refactored OpenGL symbol fetching and managment
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 2 | ||||
| -rwxr-xr-x | src/include/box64context.h | 5 | ||||
| -rw-r--r-- | src/include/gltools.h | 12 | ||||
| -rwxr-xr-x | src/include/library.h | 4 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibegl.c | 65 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibgl.c | 395 | ||||
| -rwxr-xr-x | src/wrapped/wrappedsdl1.c | 48 | ||||
| -rwxr-xr-x | src/wrapped/wrappedsdl2.c | 63 |
8 files changed, 296 insertions, 298 deletions
diff --git a/src/box64context.c b/src/box64context.c index 67f7f584..95b4a5bd 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -20,6 +20,7 @@ #include "x64emu.h" #include "signals.h" #include "rcfile.h" +#include "gltools.h" EXPORTDYN void initAllHelpers(box64context_t* context) @@ -233,6 +234,7 @@ box64context_t *NewBox64Context(int argc) return context; } +void freeALProcWrapper(box64context_t* context); EXPORTDYN void FreeBox64Context(box64context_t** context) { diff --git a/src/include/box64context.h b/src/include/box64context.h index 3e55ff44..010521e8 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -34,7 +34,7 @@ typedef struct kh_dynablocks_s kh_dynablocks_t; #endif #define DYNAMAP_SHIFT 16 -typedef void* (*procaddess_t)(const char* name); +typedef void* (*procaddress_t)(const char* name); typedef void* (*vkprocaddess_t)(void* instance, const char* name); #define MAX_SIGNAL 64 @@ -114,9 +114,6 @@ typedef struct box64context_s { uintptr_t vsyscall; // vsyscall bridge value uintptr_t vsyscalls[3]; // the 3 x86 VSyscall pseudo bridges (mapped at 0xffffffffff600000+) dlprivate_t *dlprivate; // dlopen library map - kh_symbolmap_t *glwrappers; // the map of wrapper for glProcs (for GLX or SDL1/2) - kh_symbolmap_t *glmymap; // link to the mysymbolmap of libGL - procaddess_t glxprocaddress; kh_symbolmap_t *alwrappers; // the map of wrapper for alGetProcAddress kh_symbolmap_t *almymap; // link to the mysymbolmap if libOpenAL kh_symbolmap_t *vkwrappers; // the map of wrapper for VulkanProcs (TODO: check SDL2) diff --git a/src/include/gltools.h b/src/include/gltools.h new file mode 100644 index 00000000..07bd74f7 --- /dev/null +++ b/src/include/gltools.h @@ -0,0 +1,12 @@ +#ifndef __GL_TOOLS_H__ +#define __GL_TOOLS_H__ + +typedef struct box64context_s box64context_t; + +typedef void* (*glprocaddress_t)(const char* name); + +void freeGLProcWrapper(box64context_t* context); + +void* getGLProcAddress(x64emu_t* emu, glprocaddress_t procaddr, const char* rname); + +#endif //__GL_TOOLS_H__ \ No newline at end of file diff --git a/src/include/library.h b/src/include/library.h index 48200a9e..afe108e7 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -28,10 +28,6 @@ int IsSameLib(library_t* lib, const char* path); // check if lib is same (pat int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); 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); int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); -void fillGLProcWrapper(box64context_t* context); -void freeGLProcWrapper(box64context_t* context); -void fillALProcWrapper(box64context_t* context); -void freeALProcWrapper(box64context_t* context); char** GetNeededLibsNames(library_t* lib); int GetNeededLibsN(library_t* lib); library_t* GetNeededLib(library_t* lib, int idx); diff --git a/src/wrapped/wrappedlibegl.c b/src/wrapped/wrappedlibegl.c index 7f8e7cb9..2a19ed94 100755 --- a/src/wrapped/wrappedlibegl.c +++ b/src/wrapped/wrappedlibegl.c @@ -15,6 +15,7 @@ #include "box64context.h" #include "librarian.h" #include "callback.h" +#include "gltools.h" const char* libeglName = "libEGL.so.1"; #define LIBNAME libegl @@ -23,75 +24,15 @@ const char* libeglName = "libEGL.so.1"; #include "wrappercallback.h" -// FIXME: old wrapped* type of file, cannot use generated/wrappedlibgltypes.h - -void fillGLProcWrapper(box64context_t*); -void freeProcWrapper(kh_symbolmap_t** symbolmap); - EXPORT void* my_eglGetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - if(dlsym_error && box64_log<LOG_DEBUG) printf_log(LOG_NONE, "Calling eglGetProcAddress(\"%s\") => ", rname); - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // check if glxprocaddress is filled, and search for lib and fill it if needed - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->eglGetProcAddress((void*)rname); - if(!symbol) { - if(dlsym_error && box64_log<LOG_DEBUG) printf_log(LOG_NONE, "%p\n", NULL); - return NULL; // easy - } - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) { - if(dlsym_error && box64_log<LOG_DEBUG) printf_log(LOG_NONE, "%p\n", (void*)ret); - return (void*)ret; // already bridged - } - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - if(dlsym_error && box64_log<LOG_DEBUG) printf_log(LOG_NONE, "%p\n", NULL); - if(dlsym_error && box64_log<LOG_INFO) printf_log(LOG_NONE, "Warning, no wrapper for %s\n", rname); - return NULL; - } - const char* constname = kh_key(emu->context->glwrappers, k); - AddOffsetSymbol(emu->context->maplib, symbol, rname); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - if(dlsym_error && box64_log<LOG_DEBUG) printf_log(LOG_NONE, "%p\n", (void*)ret); - return (void*)ret; - + return getGLProcAddress(emu, (glprocaddress_t)my->eglGetProcAddress, name); } - #define CUSTOM_INIT \ - getMy(lib); \ - if (!box64->glxprocaddress) \ - box64->glxprocaddress = (procaddess_t)my->eglGetProcAddress; + getMy(lib); #define CUSTOM_FINI \ freeMy(); diff --git a/src/wrapped/wrappedlibgl.c b/src/wrapped/wrappedlibgl.c index 9875847c..020f0f41 100755 --- a/src/wrapped/wrappedlibgl.c +++ b/src/wrapped/wrappedlibgl.c @@ -15,72 +15,19 @@ #include "box64context.h" #include "librarian.h" #include "callback.h" +#include "gltools.h" const char* libglName = "libGL.so.1"; #define LIBNAME libgl +static library_t* my_lib = NULL; // FIXME: old wrapped* type of file, cannot use generated/wrappedlibgltypes.h -void fillGLProcWrapper(box64context_t*); -void freeProcWrapper(kh_symbolmap_t** symbolmap); - EXPORT void* my_glXGetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_dlsym(LOG_DEBUG, "Calling glXGetProcAddress(\"%s\") => ", rname); - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // check if glxprocaddress is filled, and search for lib and fill it if needed - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = emu->context->glxprocaddress(rname); - if(!symbol) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - return NULL; // easy - } - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) { - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; // already bridged - } - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - const char* constname = kh_key(emu->context->glwrappers, k); - AddOffsetSymbol(emu->context->maplib, symbol, rname); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; - + return getGLProcAddress(emu, my_lib->w.priv, rname); } EXPORT void* my_glXGetProcAddressARB(x64emu_t* emu, void* name) __attribute__((alias("my_glXGetProcAddress"))); @@ -89,6 +36,16 @@ typedef void (*vFpp_t)(void*, void*); typedef void*(*pFp_t)(void*); typedef void (*debugProc_t)(int32_t, int32_t, uint32_t, int32_t, int32_t, void*, void*); +typedef struct gl_wrappers_s { + glprocaddress_t procaddress; + kh_symbolmap_t *glwrappers; // the map of wrapper for glProcs (for GLX or SDL1/2) + kh_symbolmap_t *glmymap; // link to the mysymbolmap of libGL +} gl_wrappers_t; + +KHASH_MAP_INIT_INT64(gl_wrappers, gl_wrappers_t*) + +static kh_gl_wrappers_t *gl_wrappers = NULL; + #define SUPER() \ GO(0) \ GO(1) \ @@ -140,106 +97,302 @@ static void* find_program_callback_Fct(void* fct) printf_log(LOG_NONE, "Warning, no more slot for libGL program_callback callback\n"); return NULL; } -#undef SUPER -EXPORT void my_glDebugMessageCallback(x64emu_t* emu, void* prod, void* param) +// glDebugMessageCallback ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallback_fct_##A = NULL; \ +static void my_glDebugMessageCallback_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallback_fct_##A) \ + return; \ + my_glDebugMessageCallback_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallback_Fct(void* fct) { - static vFpp_t DebugMessageCallback = NULL; - static int init = 1; - if(init) { - DebugMessageCallback = emu->context->glxprocaddress("glDebugMessageCallback"); - init = 0; - } - if(!DebugMessageCallback) - return; - DebugMessageCallback(find_debug_callback_Fct(prod), param); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallback_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallback_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallback_fct_##A == 0) {my_glDebugMessageCallback_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallback_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallback callback\n"); + return NULL; } -EXPORT void my_glDebugMessageCallbackARB(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); -EXPORT void my_glDebugMessageCallbackAMD(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); -EXPORT void my_glDebugMessageCallbackKHR(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); - -EXPORT int my_glXSwapIntervalMESA(int interval) +// glDebugMessageCallbackARB ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackARB_fct_##A = NULL; \ +static void my_glDebugMessageCallbackARB_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackARB_fct_##A) \ + return; \ + my_glDebugMessageCallbackARB_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackARB_Fct(void* fct) { - static iFi_t SwapIntervalMESA = NULL; - static int init = 1; - if(init) { - SwapIntervalMESA = my_context->glxprocaddress("glXSwapIntervalMESA"); - init = 0; - } - if(!SwapIntervalMESA) - return 0; - return SwapIntervalMESA(interval); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackARB_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackARB_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackARB_fct_##A == 0) {my_glDebugMessageCallbackARB_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackARB_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackARB callback\n"); + return NULL; } - -EXPORT void my_glProgramCallbackMESA(x64emu_t* emu, void* f, void* data) +// glDebugMessageCallbackAMD ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackAMD_fct_##A = NULL; \ +static void my_glDebugMessageCallbackAMD_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackAMD_fct_##A) \ + return; \ + my_glDebugMessageCallbackAMD_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackAMD_Fct(void* fct) { - static vFpp_t ProgramCallbackMESA = NULL; - static int init = 1; - if(init) { - ProgramCallbackMESA = my_context->glxprocaddress("glProgramCallbackMESA"); - init = 0; - } - if(!ProgramCallbackMESA) - return; - ProgramCallbackMESA(find_program_callback_Fct(f), data); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackAMD_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackAMD_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackAMD_fct_##A == 0) {my_glDebugMessageCallbackAMD_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackAMD_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackAMD callback\n"); + return NULL; +} +// glDebugMessageCallbackKHR ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackKHR_fct_##A = NULL; \ +static void my_glDebugMessageCallbackKHR_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackKHR_fct_##A) \ + return; \ + my_glDebugMessageCallbackKHR_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackKHR_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackKHR_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackKHR_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackKHR_fct_##A == 0) {my_glDebugMessageCallbackKHR_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackKHR_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackKHR callback\n"); + return NULL; +} +// glXSwapIntervalMESA ... +#define GO(A) \ +static iFi_t my_glXSwapIntervalMESA_fct_##A = NULL; \ +static int my_glXSwapIntervalMESA_##A(int interval) \ +{ \ + if(!my_glXSwapIntervalMESA_fct_##A) \ + return 0; \ + return my_glXSwapIntervalMESA_fct_##A(interval); \ +} +SUPER() +#undef GO +static void* find_glXSwapIntervalMESA_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glXSwapIntervalMESA_fct_##A == (iFi_t)fct) return my_glXSwapIntervalMESA_##A; + SUPER() + #undef GO + #define GO(A) if(my_glXSwapIntervalMESA_fct_##A == 0) {my_glXSwapIntervalMESA_fct_##A = (iFi_t)fct; return my_glXSwapIntervalMESA_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glXSwapIntervalMESA callback\n"); + return NULL; +} +// glProgramCallbackMESA ... +#define GO(A) \ +static vFpp_t my_glProgramCallbackMESA_fct_##A = NULL; \ +static void my_glProgramCallbackMESA_##A(x64emu_t* emu, void* f, void* data)\ +{ \ + if(!my_glProgramCallbackMESA_fct_##A) \ + return; \ + my_glProgramCallbackMESA_fct_##A(find_program_callback_Fct(f), data); \ +} +SUPER() +#undef GO +static void* find_glProgramCallbackMESA_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glProgramCallbackMESA_fct_##A == (vFpp_t)fct) return my_glProgramCallbackMESA_##A; + SUPER() + #undef GO + #define GO(A) if(my_glProgramCallbackMESA_fct_##A == 0) {my_glProgramCallbackMESA_fct_##A = (vFpp_t)fct; return my_glProgramCallbackMESA_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glProgramCallbackMESA callback\n"); + return NULL; } - void* my_GetVkProcAddr(x64emu_t* emu, void* name, void*(*getaddr)(void*)); // defined in wrappedvulkan.c -EXPORT void* my_glGetVkProcAddrNV(x64emu_t* emu, void* name) +// glGetVkProcAddrNV ... +#define GO(A) \ +static pFp_t my_glGetVkProcAddrNV_fct_##A = NULL; \ +static void* my_glGetVkProcAddrNV_##A(x64emu_t* emu, void* name) \ +{ \ + if(!my_glGetVkProcAddrNV_fct_##A) \ + return NULL; \ + return my_GetVkProcAddr(emu, name, my_glGetVkProcAddrNV_fct_##A); \ +} +SUPER() +#undef GO +static void* find_glGetVkProcAddrNV_Fct(void* fct) { - static pFp_t GetVkProcAddrNV = NULL; - static int init = 1; - if(init) { - GetVkProcAddrNV = my_context->glxprocaddress("glGetVkProcAddrNV"); - init = 0; - } - return my_GetVkProcAddr(emu, name, GetVkProcAddrNV); + if(!fct) return fct; + #define GO(A) if(my_glGetVkProcAddrNV_fct_##A == (pFp_t)fct) return my_glGetVkProcAddrNV_##A; + SUPER() + #undef GO + #define GO(A) if(my_glGetVkProcAddrNV_fct_##A == 0) {my_glGetVkProcAddrNV_fct_##A = (pFp_t)fct; return my_glGetVkProcAddrNV_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glGetVkProcAddrNV callback\n"); + return NULL; } +#undef SUPER #define PRE_INIT if(box64_libGL) {lib->w.lib = dlopen(box64_libGL, RTLD_LAZY | RTLD_GLOBAL); lib->path = strdup(box64_libGL);} else #define CUSTOM_INIT \ + my_lib = lib; \ lib->w.priv = dlsym(lib->w.lib, "glXGetProcAddress"); \ - if (!box64->glxprocaddress) \ - box64->glxprocaddress = lib->w.priv; - #include "wrappedlib_init.h" -void fillGLProcWrapper(box64context_t* context) +#define SUPER() \ + GO(vFpp_t, glDebugMessageCallback) \ + GO(vFpp_t, glDebugMessageCallbackARB) \ + GO(vFpp_t, glDebugMessageCallbackAMD) \ + GO(vFpp_t, glDebugMessageCallbackKHR) \ + GO(iFi_t, glXSwapIntervalMESA) \ + GO(vFpp_t, glProgramCallbackMESA) \ + GO(pFp_t, glGetVkProcAddrNV) \ + + +gl_wrappers_t* getGLProcWrapper(box64context_t* context, glprocaddress_t procaddress) { int cnt, ret; khint_t k; - kh_symbolmap_t * symbolmap = kh_init(symbolmap); + if(!gl_wrappers) { + gl_wrappers = kh_init(gl_wrappers); + } + k = kh_put(gl_wrappers, gl_wrappers, (uintptr_t)procaddress, &ret); + if(!ret) + return kh_value(gl_wrappers, k); + gl_wrappers_t* wrappers = kh_value(gl_wrappers, k) = (gl_wrappers_t*)calloc(1, sizeof(gl_wrappers_t)); + + wrappers->procaddress = procaddress; + wrappers->glwrappers = kh_init(symbolmap); // populates maps... cnt = sizeof(libglsymbolmap)/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { - k = kh_put(symbolmap, symbolmap, libglsymbolmap[i].name, &ret); - kh_value(symbolmap, k) = libglsymbolmap[i].w; + k = kh_put(symbolmap, wrappers->glwrappers, libglsymbolmap[i].name, &ret); + kh_value(wrappers->glwrappers, k) = libglsymbolmap[i].w; } // and the my_ symbols map cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { - k = kh_put(symbolmap, symbolmap, libglmysymbolmap[i].name, &ret); - kh_value(symbolmap, k) = libglmysymbolmap[i].w; + k = kh_put(symbolmap, wrappers->glwrappers, libglmysymbolmap[i].name, &ret); + kh_value(wrappers->glwrappers, k) = libglmysymbolmap[i].w; } - context->glwrappers = symbolmap; // my_* map - symbolmap = kh_init(symbolmap); + wrappers->glmymap = kh_init(symbolmap); cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { - k = kh_put(symbolmap, symbolmap, libglmysymbolmap[i].name, &ret); - kh_value(symbolmap, k) = libglmysymbolmap[i].w; + k = kh_put(symbolmap, wrappers->glmymap, libglmysymbolmap[i].name, &ret); + kh_value(wrappers->glmymap, k) = libglmysymbolmap[i].w; } - context->glmymap = symbolmap; + return wrappers; } void freeGLProcWrapper(box64context_t* context) { if(!context) return; - if(context->glwrappers) - kh_destroy(symbolmap, context->glwrappers); - if(context->glmymap) - kh_destroy(symbolmap, context->glmymap); - context->glwrappers = NULL; - context->glmymap = NULL; + if(!gl_wrappers) + return; + gl_wrappers_t* wrappers; + kh_foreach_value(gl_wrappers, wrappers, + if(wrappers->glwrappers) + kh_destroy(symbolmap, wrappers->glwrappers); + if(wrappers->glmymap) + kh_destroy(symbolmap, wrappers->glmymap); + wrappers->glwrappers = NULL; + wrappers->glmymap = NULL; + ); + kh_destroy(gl_wrappers, gl_wrappers); + gl_wrappers = NULL; } + +void* getGLProcAddress(x64emu_t* emu, glprocaddress_t procaddr, const char* rname) +{ + khint_t k; + printf_dlsym(LOG_DEBUG, "Calling getGLProcAddress[%p](\"%s\") => ", procaddr, rname); + gl_wrappers_t* wrappers = getGLProcWrapper(emu->context, procaddr); + // check if glxprocaddress is filled, and search for lib and fill it if needed + // get proc adress using actual glXGetProcAddress + k = kh_get(symbolmap, wrappers->glmymap, rname); + int is_my = (k==kh_end(wrappers->glmymap))?0:1; + void* symbol; + if(is_my) { + // try again, by using custom "my_" now... + #define GO(A, B) else if(!strcmp(rname, #B)) symbol = find_##B##_Fct(procaddr(rname)); + if(0) {} + SUPER() + else { + printf_log(LOG_NONE, "Warning, %s defined as GOM, but find_%s_Fct not defined\n", rname, rname); + char tmp[200]; + strcpy(tmp, "my_"); + strcat(tmp, rname); + symbol = dlsym(emu->context->box64lib, tmp); + } + #undef GO + #undef SUPER + } else + symbol = procaddr(rname); + if(!symbol) { + printf_dlsym(LOG_DEBUG, "%p\n", NULL); + return NULL; // easy + } + // check if alread bridged + uintptr_t ret = CheckBridged(emu->context->system, symbol); + if(ret) { + printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); + return (void*)ret; // already bridged + } + // get wrapper + k = kh_get(symbolmap, wrappers->glwrappers, rname); + if(k==kh_end(wrappers->glwrappers) && strstr(rname, "ARB")==NULL) { + // try again, adding ARB at the end if not present + char tmp[200]; + strcpy(tmp, rname); + strcat(tmp, "ARB"); + k = kh_get(symbolmap, wrappers->glwrappers, tmp); + } + if(k==kh_end(wrappers->glwrappers) && strstr(rname, "EXT")==NULL) { + // try again, adding EXT at the end if not present + char tmp[200]; + strcpy(tmp, rname); + strcat(tmp, "EXT"); + k = kh_get(symbolmap, wrappers->glwrappers, tmp); + } + if(k==kh_end(wrappers->glwrappers)) { + printf_dlsym(LOG_DEBUG, "%p\n", NULL); + printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname); + return NULL; + } + const char* constname = kh_key(wrappers->glwrappers, k); + AddOffsetSymbol(emu->context->maplib, symbol, rname); + ret = AddBridge(emu->context->system, kh_value(wrappers->glwrappers, k), symbol, 0, constname); + printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); + return (void*)ret; +} \ No newline at end of file diff --git a/src/wrapped/wrappedsdl1.c b/src/wrapped/wrappedsdl1.c index 97353568..4ebfb31e 100755 --- a/src/wrapped/wrappedsdl1.c +++ b/src/wrapped/wrappedsdl1.c @@ -16,6 +16,7 @@ #include "emu/x64emu_private.h" #include "box64context.h" #include "sdl1rwops.h" +#include "gltools.h" #include "x64trace.h" #include "threads.h" @@ -349,56 +350,11 @@ EXPORT void my_SDL_KillThread(x64emu_t* emu, void* p) my->SDL_KillThread(p); } -void fillGLProcWrapper(box64context_t* context); EXPORT void* my_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_log(LOG_DEBUG, "Calling SDL_GL_GetProcAddress(%s)\n", rname); - // check if glxprocaddress is filled, and search for lib and fill it if needed - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->SDL_GL_GetProcAddress(name); - if(!symbol) - return NULL; // easy - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) - return (void*)ret; // already bridged - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - AddOffsetSymbol(emu->context->maplib, symbol, rname); - const char* constname = kh_key(emu->context->glwrappers, k); - return (void*)AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); + return getGLProcAddress(emu, (glprocaddress_t)my->SDL_GL_GetProcAddress, rname); } // DL functions from wrappedlibdl.c diff --git a/src/wrapped/wrappedsdl2.c b/src/wrapped/wrappedsdl2.c index d68ca1a9..40b39edf 100755 --- a/src/wrapped/wrappedsdl2.c +++ b/src/wrapped/wrappedsdl2.c @@ -18,6 +18,7 @@ #include "sdl2rwops.h" #include "myalign.h" #include "threads.h" +#include "gltools.h" #include "generated/wrappedsdl2defs.h" @@ -645,71 +646,11 @@ EXPORT void my2_SDL_Log(x64emu_t* emu, void* fmt, void *b) { my->SDL_LogMessageV(0, 3, fmt, VARARGS); } -void fillGLProcWrapper(box64context_t*); EXPORT void* my2_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_dlsym(LOG_DEBUG, "Calling SDL_GL_GetProcAddress(%s) => ", rname); - // check if glxprocaddress is filled, and search for lib and fill it if needed - if(!emu->context->glxprocaddress) - emu->context->glxprocaddress = (procaddess_t)my->SDL_GL_GetProcAddress; - if(!emu->context->glwrappers) { - fillGLProcWrapper(emu->context); - // check if libGL is loaded, load it if not (helps DeadCells) - if(!my_glhandle && !GetLibInternal(box64_libGL?box64_libGL:"libGL.so.1")) { - // use a my_dlopen to actually open that lib, like SDL2 is doing... - my_glhandle = my_dlopen(emu, box64_libGL?box64_libGL:"libGL.so.1", RTLD_LAZY|RTLD_GLOBAL); - } - } - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->SDL_GL_GetProcAddress(name); - if(!symbol) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - return NULL; // easy - } - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) { - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; // already bridged - } - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - AddOffsetSymbol(emu->context->maplib, symbol, rname); - const char* constname = kh_key(emu->context->glwrappers, k); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; + return getGLProcAddress(emu, (glprocaddress_t)my->SDL_GL_GetProcAddress, rname); } #define nb_once 16 |