]> git.cworth.org Git - fips/commitdiff
glwrap: Don't hardcode "libGL.so.1" for looking up real OpenGL symbols
authorCarl Worth <cworth@cworth.org>
Wed, 3 Jul 2013 00:33:12 +0000 (17:33 -0700)
committerCarl Worth <cworth@cworth.org>
Wed, 3 Jul 2013 00:37:49 +0000 (17:37 -0700)
As preparation for testing using GLESv2 we need to ensure that our GL
wrappers are prepared for an OpenGL implementation in either the
libGL.so.1 library or in libGLESv2.so.2.

When the application is directly linked to an OpenGL implementation,
we don't care about the name at all. In this case, we can simply call
dlsym with RTLD_NEXT to find the real, underlying OpenGL symbols.

But when an application uses dlopen to load the OpenGL library, we
want to carefully call dlsym with a handle for the same library that
the application uses. Previously, the glwrap code was unconditionally
calling dlopen for "libGL.so" and that's not what we want.

Instead, we now have our dlopen wrapper watch for any dlopen of a
library whose name begins with "libGL" and then stashing the returned
handle via a new glwrap_set_gl_handle call. The stashed handle will
then be used by dlsym calls within glwrap.

dlwrap.c
dlwrap.h
glwrap.c
glwrap.h

index aff9e625eda298680cc890f88061ea1845d97e65..858b99b6d5a6b1e41b5b94aad3d4299dcc69fb35 100644 (file)
--- a/dlwrap.c
+++ b/dlwrap.c
@@ -29,6 +29,8 @@
 
 #include "dlwrap.h"
 
+#include "glwrap.h"
+
 void *libfips_handle;
 
 typedef void * (* fips_dlopen_t)(const char * filename, int flag);
@@ -86,6 +88,13 @@ dlopen (const char *filename, int flag)
        if (! find_wrapped_library_index (filename, &index))
                return ret;
 
+       /* When the application dlopens any wrapped library starting
+        * with 'libGL', (whether libGL.so.1 or libGLESv2.so.2), let's
+        * continue to use that library handle for future lookups of
+        * OpenGL functions. */
+       if (STRNCMP_LITERAL (filename, "libGL") == 0)
+               glwrap_set_gl_handle (ret);
+
        assert (index < ARRAY_SIZE(orig_handles));
        orig_handles[index] = ret;
 
index 1dba14a9f569f03ac1f7b2e6f61ca4518838e470..cad5a62f7d86a901521fcd74e07634d4ee6ca8ed 100644 (file)
--- a/dlwrap.h
+++ b/dlwrap.h
@@ -22,6 +22,7 @@
 #ifndef DLWRAP_H
 #define DLWRAP_H
 
+#define _GNU_SOURCE
 #include <dlfcn.h>
 
 /* Call the *real* dlopen. We have our own wrapper for dlopen that, of
index a7d62c5c1ef2be57d650591302923197c0fbb05f..0ae295a87082212b59d764f8b89250c2ab5c68b8 100644 (file)
--- a/glwrap.c
+++ b/glwrap.c
@@ -19,6 +19,8 @@
  * THE SOFTWARE.
  */
 
+#include "dlwrap.h"
+
 /* The prototypes for some OpenGL functions changed at one point from:
  *
  *     const void* *indices
 
 #include "metrics.h"
 
-#include "dlwrap.h"
-
 static int inside_new_list = 0;
 
+static void *gl_handle;
+
+void
+glwrap_set_gl_handle (void *handle)
+{
+       if (gl_handle == NULL)
+               gl_handle = handle;
+}
+
 void *
 glwrap_lookup (char *name)
 {
-       const char *libgl_filename = "libGL.so.1";
-       static void *libgl_handle = NULL;
-
-       if (! libgl_handle) {
-               libgl_handle = dlwrap_real_dlopen (libgl_filename, RTLD_NOW | RTLD_DEEPBIND);
-               if (! libgl_handle) {
-                       fprintf (stderr, "Error: Failed to dlopen %s\n",
-                                libgl_filename);
-                       exit (1);
-               }
+       void *ret;
+
+       /* We don't call dlopen here to find the library in which to
+        * perform a dlsym lookup. That's because the application may
+        * be loading libGL.so or libGLESv2.so for its OpenGL symbols.
+        *
+        * So we instead watch for one of those filenames to go by in
+        * our dlopen wrapper, which will then call
+        * glwrap_set_gl_handle to give us the handle to use here.
+        *
+
+        * If the application hasn't called dlopen on a "libGL"
+        * library, then presumably the application is linked directly
+        * to an OpenGL implementation. In this case, we can use
+        * RTLD_NEXT to find the symbol.
+        */
+       if (gl_handle == NULL)
+               gl_handle = RTLD_NEXT;
+
+       ret = dlwrap_real_dlsym (gl_handle, name);
+
+       if (ret == NULL) {
+               fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
+                        name);
+               exit (1);
        }
 
-       return dlwrap_real_dlsym (libgl_handle, name);
+       return ret;
 }
 
 /* Execute an OpenGL call and time it with a GPU metrics counter. */
index bd2e265dac5e9d26c7d7a12821e08ea9f0c0e40a..6acf3fcdb98cc00c86f690d217a070ddc1d0a96e 100644 (file)
--- a/glwrap.h
+++ b/glwrap.h
 void *
 glwrap_lookup (char *name);
 
+/* Register a dlopened handle to be used by glwrap. */
+void
+glwrap_set_gl_handle (void *handle);
+
 /* Defer to the real 'function' (from libGL.so) to do the real work.
  * The symbol is looked up once and cached in a static variable for
  * future uses.