#include "dlwrap.h"
+#include "glwrap.h"
+
void *libfips_handle;
typedef void * (* fips_dlopen_t)(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;
* 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. */
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.