From b415a359f361f6ba4d59e467756023df0f38d569 Mon Sep 17 00:00:00 2001 From: Elias Vanderstuyft Date: Tue, 18 Oct 2016 22:18:06 +0200 Subject: [PATCH 1/4] Remove code duplication by using C macros: add and use RETURN_ON_MATCH(function_name) in dlsym() --- frametime.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/frametime.c b/frametime.c index 5dc3e4f..e44e1a8 100644 --- a/frametime.c +++ b/frametime.c @@ -93,14 +93,19 @@ static void init_dlsym() { void *dlsym(void *handle, const char *symbol) { // High evil wrapping this function. - if (symbol && !strcmp(symbol, "glXGetProcAddressARB")) - return glXGetProcAddressARB; - if (symbol && !strcmp(symbol, "glXSwapBuffers")) - return glXSwapBuffers; -#ifndef NO_EGL - if (symbol && !strcmp(symbol, "eglSwapBuffers")) - return eglSwapBuffers; -#endif +# define RETURN_ON_MATCH(function_name) \ + do { \ + if (symbol && !strcmp(symbol, #function_name)) \ + return function_name; \ + } while (0) + + RETURN_ON_MATCH(glXGetProcAddressARB); + RETURN_ON_MATCH(glXSwapBuffers); +# ifndef NO_EGL + RETURN_ON_MATCH(eglSwapBuffers); +# endif + +# undef RETURN_ON_MATCH if (!real_dlsym) init_dlsym(); From 4490ca6e68b3c3bf794b07d8ab1e8d6dd8d3fb59 Mon Sep 17 00:00:00 2001 From: Elias Vanderstuyft Date: Sun, 2 Oct 2016 17:08:06 +0200 Subject: [PATCH 2/4] Refactor the code by adding some currently unneeded error handling to init(), which will go away with the later patches by using C macros --- frametime.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/frametime.c b/frametime.c index e44e1a8..476a51d 100644 --- a/frametime.c +++ b/frametime.c @@ -154,13 +154,26 @@ static void init() { init_dlsym(); dlerror(); - real_glXSwapBuffers = real_dlsym(RTLD_NEXT, "glXSwapBuffers"); + real_glXGetProcAddressARB = real_dlsym(RTLD_NEXT, "glXGetProcAddressARB"); const char *err = dlerror(); if (err) die(PREFIX "dlsym failed: %s\n", err); - real_glXGetProcAddressARB = real_dlsym(RTLD_NEXT, "glXGetProcAddressARB"); + // If the app loads libs dynamically, the symbol may be NULL. + if (!real_glXGetProcAddressARB) { + void *libgl = dlopen("libGL.so", RTLD_LAZY); + if (!libgl) + die(PREFIX "dynamic libGL failed\n"); + real_glXGetProcAddressARB = real_dlsym(libgl, "glXGetProcAddressARB"); + } + + dlerror(); + real_glXSwapBuffers = real_dlsym(RTLD_NEXT, "glXSwapBuffers"); + + err = dlerror(); + if (err) + die(PREFIX "dlsym failed: %s\n", err); // If the app loads libs dynamically, the symbol may be NULL. if (!real_glXSwapBuffers) { @@ -168,7 +181,6 @@ static void init() { if (!libgl) die(PREFIX "dynamic libGL failed\n"); real_glXSwapBuffers = real_dlsym(libgl, "glXSwapBuffers"); - real_glXGetProcAddressARB = real_dlsym(libgl, "glXGetProcAddressARB"); } #ifndef NO_EGL From acf1625fabae10825036c5eb329bccffeccdd27f Mon Sep 17 00:00:00 2001 From: Elias Vanderstuyft Date: Sun, 2 Oct 2016 17:20:29 +0200 Subject: [PATCH 3/4] Error out when symbol was not found in dynamic library --- frametime.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frametime.c b/frametime.c index 476a51d..633489e 100644 --- a/frametime.c +++ b/frametime.c @@ -166,6 +166,8 @@ static void init() { if (!libgl) die(PREFIX "dynamic libGL failed\n"); real_glXGetProcAddressARB = real_dlsym(libgl, "glXGetProcAddressARB"); + if (!real_glXGetProcAddressARB) + die(PREFIX "Failed to find glXGetProcAddressARB in libGL.so\n"); } dlerror(); @@ -181,6 +183,8 @@ static void init() { if (!libgl) die(PREFIX "dynamic libGL failed\n"); real_glXSwapBuffers = real_dlsym(libgl, "glXSwapBuffers"); + if (!real_glXSwapBuffers) + die(PREFIX "Failed to find glXSwapBuffers in libGL.so\n"); } #ifndef NO_EGL @@ -197,6 +201,8 @@ static void init() { if (!libegl) die(PREFIX "dynamic libEGL failed\n"); real_eglSwapBuffers = real_dlsym(libegl, "eglSwapBuffers"); + if (!real_eglSwapBuffers) + die(PREFIX "Failed to find eglSwapBuffers in libEGL.so\n"); } #endif } From dda8962dadcae8ee511a87d48752814b520531d4 Mon Sep 17 00:00:00 2001 From: Elias Vanderstuyft Date: Sun, 30 Oct 2016 22:39:13 +0100 Subject: [PATCH 4/4] Remove code duplication: add load_func_from_next() and load_func_from_lib() and use them in init() --- frametime.c | 87 +++++++++++++++++++++-------------------------------- 1 file changed, 35 insertions(+), 52 deletions(-) diff --git a/frametime.c b/frametime.c index 633489e..26312fe 100644 --- a/frametime.c +++ b/frametime.c @@ -137,6 +137,36 @@ EGLBoolean eglSwapBuffers(EGLDisplay display, EGLSurface surface) { } #endif +static void *load_func_from_next(const char * const function_name) { + + dlerror(); + void * const real_function = real_dlsym(RTLD_NEXT, function_name); + + const char * const err = dlerror(); + if (err) + die(PREFIX "dlsym failed: %s\n", err); + + return real_function; +} + +static void *load_func_from_lib(const char * const function_name, const char * const library_name) { + + // If possible, load from the next object such that we don't have to load the lib. + void *real_function = load_func_from_next(function_name); + + if (!real_function) { + void * const lib = dlopen(library_name, RTLD_LAZY); + if (!lib) + die(PREFIX "Failed to open %s\n", library_name); + + real_function = real_dlsym(lib, function_name); + if (!real_function) + die(PREFIX "Failed to find %s in %s\n", function_name, library_name); + } + + return real_function; +} + static void init() __attribute__((constructor)); static void deinit() __attribute__((destructor)); @@ -153,58 +183,11 @@ static void init() { if (!real_dlsym) init_dlsym(); - dlerror(); - real_glXGetProcAddressARB = real_dlsym(RTLD_NEXT, "glXGetProcAddressARB"); - - const char *err = dlerror(); - if (err) - die(PREFIX "dlsym failed: %s\n", err); - - // If the app loads libs dynamically, the symbol may be NULL. - if (!real_glXGetProcAddressARB) { - void *libgl = dlopen("libGL.so", RTLD_LAZY); - if (!libgl) - die(PREFIX "dynamic libGL failed\n"); - real_glXGetProcAddressARB = real_dlsym(libgl, "glXGetProcAddressARB"); - if (!real_glXGetProcAddressARB) - die(PREFIX "Failed to find glXGetProcAddressARB in libGL.so\n"); - } - - dlerror(); - real_glXSwapBuffers = real_dlsym(RTLD_NEXT, "glXSwapBuffers"); - - err = dlerror(); - if (err) - die(PREFIX "dlsym failed: %s\n", err); - - // If the app loads libs dynamically, the symbol may be NULL. - if (!real_glXSwapBuffers) { - void *libgl = dlopen("libGL.so", RTLD_LAZY); - if (!libgl) - die(PREFIX "dynamic libGL failed\n"); - real_glXSwapBuffers = real_dlsym(libgl, "glXSwapBuffers"); - if (!real_glXSwapBuffers) - die(PREFIX "Failed to find glXSwapBuffers in libGL.so\n"); - } - -#ifndef NO_EGL - dlerror(); - real_eglSwapBuffers = real_dlsym(RTLD_NEXT, "eglSwapBuffers"); - - err = dlerror(); - if (err) - die(PREFIX "dlsym failed: %s\n", err); - - // If the app loads libs dynamically, the symbol may be NULL. - if (!real_eglSwapBuffers) { - void *libegl = dlopen("libEGL.so", RTLD_LAZY); - if (!libegl) - die(PREFIX "dynamic libEGL failed\n"); - real_eglSwapBuffers = real_dlsym(libegl, "eglSwapBuffers"); - if (!real_eglSwapBuffers) - die(PREFIX "Failed to find eglSwapBuffers in libEGL.so\n"); - } -#endif + real_glXGetProcAddressARB = load_func_from_lib("glXGetProcAddressARB", "libGL.so"); + real_glXSwapBuffers = load_func_from_lib("glXSwapBuffers", "libGL.so"); +# ifndef NO_EGL + real_eglSwapBuffers = load_func_from_lib("eglSwapBuffers", "libEGL.so"); +# endif } static void deinit() {