From: José Fonseca Date: Sat, 16 Apr 2011 12:41:24 +0000 (+0100) Subject: Fix tracing of apps that use dlsym, such as OpenArena. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=85a20681460af82d3542a9f9d016b1b2698b7fa4;p=apitrace Fix tracing of apps that use dlsym, such as OpenArena. --- diff --git a/glproc.py b/glproc.py index fa1db1e..2fde623 100644 --- a/glproc.py +++ b/glproc.py @@ -421,7 +421,8 @@ class GlDispatcher(Dispatcher): print '# define __getPrivateProcAddress(name) __wglGetProcAddress(name)' print ' static inline PROC __stdcall __wglGetProcAddress(const char * lpszProc);' print '# else' - print '# define __getPublicProcAddress(name) dlsym(RTLD_NEXT, name)' + print ' static void *libgl_handle = RTLD_NEXT;' + print '# define __getPublicProcAddress(name) dlsym(libgl_handle, name)' print '# define __getPrivateProcAddress(name) __glXGetProcAddressARB((const GLubyte *)(name))' print ' static inline __GLXextFuncPtr __glXGetProcAddressARB(const GLubyte * procName);' print '# endif' diff --git a/glxtrace.py b/glxtrace.py index e1a5aa5..050a082 100644 --- a/glxtrace.py +++ b/glxtrace.py @@ -48,6 +48,10 @@ if __name__ == '__main__': print print '#include ' print '#include ' + print + print '#ifndef _GNU_SOURCE' + print '#define _GNU_SOURCE // for dladdr' + print '#endif' print '#include ' print print '#include "trace_write.hpp"' @@ -80,4 +84,54 @@ if __name__ == '__main__': print ' return procPtr;' print '}' print + print r''' + +/* + * 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) +{ + typedef void * (*PFNDLOPEN)(const char *, int); + static PFNDLOPEN dlopen_ptr = NULL; + void *handle; + + if (!dlopen_ptr) { + dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen"); + if (!dlopen_ptr) { + OS::DebugMessage("error: dlsym(RTLD_NEXT, \"dlopen\") failed\n"); + return NULL; + } + } + + handle = dlopen_ptr(filename, flag); + + if (filename && handle) { + if (0) { + OS::DebugMessage("warning: dlopen(\"%s\", 0x%x)\n", filename, flag); + } + + // FIXME: handle absolute paths and other versions + if (strcmp(filename, "libGL.so.1") == 0) { + // Use the true libGL.so handle instead of RTLD_NEXT from now on + libgl_handle = handle; + + // Get the file path for our shared object, and use it instead + static int dummy = 0xdeedbeef; + 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); + } else { + OS::DebugMessage("warning: dladdr() failed\n"); + } + } + } + + return handle; +} + +''' print '} /* extern "C" */'