+
+/*
+ * Lookup a libGL symbol
+ */
+static void * __dlsym(const char *symbol)
+{
+ void *result;
+
+ if (!libgl_handle) {
+ /*
+ * The app doesn't directly link against libGL.so, nor does it directly
+ * dlopen it. So we have to load it ourselves.
+ */
+
+ const char * libgl_filename = getenv("TRACE_LIBGL");
+
+ if (!libgl_filename) {
+ /*
+ * Try to use whatever libGL.so the library is linked against.
+ */
+
+ result = dlsym(RTLD_NEXT, symbol);
+ if (result) {
+ libgl_handle = RTLD_NEXT;
+ return result;
+ }
+
+ libgl_filename = "libGL.so.1";
+ }
+
+ /*
+ * It would have been preferable to use RTLD_LOCAL to ensure that the
+ * application can never access libGL.so symbols directly, but this
+ * won't work, given libGL.so often loads a driver specific SO and
+ * exposes symbols to it.
+ */
+
+ libgl_handle = __dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY);
+ if (!libgl_handle) {
+ OS::DebugMessage("error: couldn't find libGL.so\n");
+ return NULL;
+ }
+ }
+
+ return dlsym(libgl_handle, symbol);
+}
+
+