From: José Fonseca Date: Thu, 21 Apr 2011 09:32:45 +0000 (+0100) Subject: Handle correctly apps that don't directly link/load libGL.so X-Git-Tag: 2.0_alpha^2~1025 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=68b140539fa6913955210ffab6d8a21c63253e2d;p=tools%2Fapitrace.git Handle correctly apps that don't directly link/load libGL.so --- diff --git a/glproc.py b/glproc.py index e1e7d16..29031b7 100644 --- a/glproc.py +++ b/glproc.py @@ -421,9 +421,9 @@ class GlDispatcher(Dispatcher): print '# define __getPrivateProcAddress(name) __wglGetProcAddress(name)' print ' static inline PROC __stdcall __wglGetProcAddress(const char * lpszProc);' print '# else' - print ' static void *libgl_handle = RTLD_NEXT;' - print '# define __getPublicProcAddress(name) dlsym(libgl_handle, name)' + print '# define __getPublicProcAddress(name) __dlsym(name)' print '# define __getPrivateProcAddress(name) __glXGetProcAddressARB((const GLubyte *)(name))' + print ' static void * __dlsym(const char *symbol);' print ' static inline __GLXextFuncPtr __glXGetProcAddressARB(const GLubyte * procName);' print '# endif' print '# define __abort() Trace::Abort()' diff --git a/glxtrace.py b/glxtrace.py index 7f5426f..9e671d6 100644 --- a/glxtrace.py +++ b/glxtrace.py @@ -86,17 +86,17 @@ if __name__ == '__main__': print print r''' + +static void *libgl_handle = NULL; + + /* - * Several applications, such as Quake3, use dlopen("libGL.so.1"), but - * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore - * we need to intercept the dlopen() call here, and redirect to our wrapper - * shared object. + * Invoke the true dlopen() function. */ -void *dlopen(const char *filename, int flag) +static void *__dlopen(const char *filename, int flag) { typedef void * (*PFNDLOPEN)(const char *, int); static PFNDLOPEN dlopen_ptr = NULL; - void *handle; if (!dlopen_ptr) { dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen"); @@ -106,7 +106,21 @@ void *dlopen(const char *filename, int flag) } } - handle = dlopen_ptr(filename, flag); + return dlopen_ptr(filename, flag); +} + + +/* + * Several applications, such as Quake3, use dlopen("libGL.so.1"), but + * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore + * we need to intercept the dlopen() call here, and redirect to our wrapper + * shared object. + */ +void *dlopen(const char *filename, int flag) +{ + void *handle; + + handle = __dlopen(filename, flag); if (filename && handle) { if (0) { @@ -124,7 +138,7 @@ void *dlopen(const char *filename, int flag) Dl_info info; if (dladdr(&dummy, &info)) { OS::DebugMessage("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag); - handle = dlopen_ptr(info.dli_fname, flag); + handle = __dlopen(info.dli_fname, flag); } else { OS::DebugMessage("warning: dladdr() failed\n"); } @@ -134,5 +148,39 @@ void *dlopen(const char *filename, int flag) return handle; } +} /* extern "C" */ + + +/* + * Lookup a libGL symbol + */ +static void * __dlsym(const char *symbol) +{ + void *result; + + if (!libgl_handle) { + /* + * Try to use whatever libGL.so the library is linked against. + */ + result = dlsym(RTLD_NEXT, symbol); + if (result) { + libgl_handle = RTLD_NEXT; + return result; + } + + /* + * The app doesn't directly link against libGL.so, nor does it directly + * dlopen it. So we have to load it ourselves. + */ + libgl_handle = __dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL); + if (!libgl_handle) { + OS::DebugMessage("error: couldn't find libGL.so\n"); + return NULL; + } + } + + return dlsym(libgl_handle, symbol); +} + + ''' - print '} /* extern "C" */'