]> git.cworth.org Git - glfps/commitdiff
Wrap dlsym as well
authorCarl Worth <cworth@cworth.org>
Sat, 21 Sep 2013 00:32:26 +0000 (17:32 -0700)
committerCarl Worth <cworth@cworth.org>
Mon, 23 Sep 2013 14:14:19 +0000 (07:14 -0700)
At this point, everything in the glfps-test suite passes.

glfps.c

diff --git a/glfps.c b/glfps.c
index a23dd2098d22289d61c2f9351194751d6c7fa556..6c9cd4988bfb46c055f7fcd8922e72d75f985535 100644 (file)
--- a/glfps.c
+++ b/glfps.c
@@ -2,6 +2,7 @@
 #include <dlfcn.h>
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <X11/Xlib.h>
 #include <GL/gl.h>
@@ -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;
+}