From 92d90669273fd23be351ebbf997f5d461b25ee18 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 20 Sep 2013 17:32:26 -0700 Subject: [PATCH] Wrap dlsym as well At this point, everything in the glfps-test suite passes. --- glfps.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/glfps.c b/glfps.c index a23dd20..6c9cd49 100644 --- a/glfps.c +++ b/glfps.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -35,43 +36,88 @@ on_each_frame (void) count++; } +static void *do_real_dlsym (void *handle, const char *symbol); + +static typeof(&glXSwapBuffers) real_glXSwapBuffers; + void glXSwapBuffers (Display *dpy, GLXDrawable drawable) { - static typeof(&glXSwapBuffers) real_glXSwapBuffers = NULL; - if (real_glXSwapBuffers == NULL) - real_glXSwapBuffers = dlsym (RTLD_NEXT, "glXSwapBuffers"); + real_glXSwapBuffers = do_real_dlsym (RTLD_NEXT, "glXSwapBuffers"); on_each_frame (); real_glXSwapBuffers (dpy, drawable); } +static typeof(&glXGetProcAddressARB) real_glXGetProcAddressARB; + void (*glXGetProcAddressARB (const GLubyte *func))(void) { - static typeof(&glXGetProcAddressARB) real_glXGetProcAddressARB = NULL; - if (strcmp((char *) func, "glXSwapBuffers") == 0) return (void*) glXSwapBuffers; if (real_glXGetProcAddressARB == NULL) - real_glXGetProcAddressARB = dlsym (RTLD_NEXT, "glXGetProcAddressARB"); + real_glXGetProcAddressARB = do_real_dlsym (RTLD_NEXT, "glXGetProcAddressARB"); return real_glXGetProcAddressARB (func); } +static typeof(&glXGetProcAddress) real_glXGetProcAddress; + void (*glXGetProcAddress (const GLubyte *func))(void) { - static typeof(&glXGetProcAddress) real_glXGetProcAddress = NULL; - if (strcmp((char *) func, "glXSwapBuffers") == 0) return (void*) glXSwapBuffers; if (real_glXGetProcAddress == NULL) - real_glXGetProcAddress = dlsym (RTLD_NEXT, "glXGetProcAddress"); + real_glXGetProcAddress = do_real_dlsym (RTLD_NEXT, "glXGetProcAddress"); return real_glXGetProcAddress (func); } + +/* We rely on an internal symbol within glibc in order to be able to + * get a handle on the real dlsym function, (we can't call dlsym to + * find the address of dlsym itself of course). */ +void * __libc_dlsym(void *, const char *); + +static void * +do_real_dlsym (void *handle, const char *symbol) +{ + static typeof(&dlsym) real_dlsym = NULL; + + if (real_dlsym == NULL) { + void *libdl_handle = dlopen ("libdl.so.2", RTLD_LAZY); + real_dlsym = __libc_dlsym(libdl_handle, "dlsym"); + } + + return real_dlsym (handle, symbol); +} + +void * +dlsym (void *handle, const char *symbol) +{ + void *ret; + + ret = do_real_dlsym (handle, symbol); + + if (strcmp (symbol, "glXSwapBuffers") == 0) { + real_glXSwapBuffers = ret; + return &glXSwapBuffers; + } + + if (strcmp (symbol, "glXGetProcAddressARB") == 0) { + real_glXGetProcAddressARB = ret; + return &glXGetProcAddressARB; + } + + if (strcmp (symbol, "glXGetProcAddress") == 0) { + real_glXGetProcAddress = ret; + return &glXGetProcAddress; + } + + return ret; +} -- 2.43.0