From: Alexander Monakov Date: Fri, 3 May 2013 17:03:27 +0000 (+0400) Subject: Implement interposing of dlopen on Android X-Git-Url: https://git.notmuchmail.org/git?a=commitdiff_plain;h=d6aa74c803556e4eb82919aef6f0edb06a5811aa;p=apitrace Implement interposing of dlopen on Android Consolidate all implementations of unredirected dlopen in one place. Use unredirected dlopen is glproc_egl.cpp as done in glproc_gl.cpp. Check that tracing is enabled before redirecting dlopen. Signed-off-by: José Fonseca --- diff --git a/dispatch/dlopen.hpp b/dispatch/dlopen.hpp new file mode 100644 index 0000000..cb59a44 --- /dev/null +++ b/dispatch/dlopen.hpp @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Provides access to real dlopen, as tracing libraries interpose it. + */ + +#ifndef _DLOPEN_HPP_ +#define _DLOPEN_HPP_ + +#include + +#include "os.hpp" + + +/* + * Invoke the true dlopen() function. + */ +static void *_dlopen(const char *filename, int flag) +{ + typedef void * (*PFN_DLOPEN)(const char *, int); + static PFN_DLOPEN dlopen_ptr = NULL; + + if (!dlopen_ptr) { +#ifdef ANDROID + /* Android does not have dlopen in libdl.so; instead, the + * implementation is available in the dynamic linker itself. + * Oddly enough, we still can interpose it, but need to use + * RTLD_DEFAULT to get pointer to the original function. */ + dlopen_ptr = (PFN_DLOPEN)dlsym(RTLD_DEFAULT, "dlopen"); +#else + dlopen_ptr = (PFN_DLOPEN)dlsym(RTLD_NEXT, "dlopen"); +#endif + if (!dlopen_ptr) { + os::log("apitrace: error: failed to look up real dlopen\n"); + return NULL; + } + } + + return dlopen_ptr(filename, flag); +} + +#endif /* _DLOPEN_HPP_ */ diff --git a/dispatch/glproc_egl.cpp b/dispatch/glproc_egl.cpp index c77c444..abba727 100644 --- a/dispatch/glproc_egl.cpp +++ b/dispatch/glproc_egl.cpp @@ -28,7 +28,7 @@ #if !defined(_WIN32) -#include +#include "dlopen.hpp" #endif @@ -79,7 +79,7 @@ _getPublicProcAddress(const char *procName) if (procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') { static void *libEGL = NULL; if (!libEGL) { - libEGL = dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY); + libEGL = _dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY); if (!libEGL) { return NULL; } @@ -93,7 +93,7 @@ _getPublicProcAddress(const char *procName) static void *libGLESv2 = NULL; if (!libGLESv2) { - libGLESv2 = dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY); + libGLESv2 = _dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY); } if (libGLESv2) { sym = dlsym(libGLESv2, procName); @@ -104,7 +104,7 @@ _getPublicProcAddress(const char *procName) static void *libGLESv1 = NULL; if (!libGLESv1) { - libGLESv1 = dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY); + libGLESv1 = _dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY); } if (libGLESv1) { sym = dlsym(libGLESv1, procName); diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp index 8e1216f..1f3e9fc 100644 --- a/dispatch/glproc_gl.cpp +++ b/dispatch/glproc_gl.cpp @@ -29,7 +29,7 @@ #if !defined(_WIN32) #include // for symlink -#include +#include "dlopen.hpp" #endif @@ -145,27 +145,6 @@ _getPrivateProcAddress(const char *procName) #else -/* - * Invoke the true dlopen() function. - */ -static void * -_dlopen(const char *filename, int flag) -{ - typedef void * (*PFNDLOPEN)(const char *, int); - static PFNDLOPEN dlopen_ptr = NULL; - - if (!dlopen_ptr) { - dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen"); - if (!dlopen_ptr) { - os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n"); - return NULL; - } - } - - return dlopen_ptr(filename, flag); -} - - /* * Lookup a libGL symbol */ diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py index 0c7ebb6..8c4a46a 100644 --- a/wrappers/egltrace.py +++ b/wrappers/egltrace.py @@ -112,7 +112,7 @@ class EglTracer(GlTracer): if __name__ == '__main__': print '#include ' print '#include ' - print '#include ' + print '#include "dlopen.hpp"' print print '#include "trace_writer_local.hpp"' print @@ -137,31 +137,6 @@ if __name__ == '__main__': print r''' -/* - * Android does not support LD_PRELOAD. - */ -#if !defined(ANDROID) - - -/* - * Invoke the true dlopen() function. - */ -static void *_dlopen(const char *filename, int flag) -{ - typedef void * (*PFN_DLOPEN)(const char *, int); - static PFN_DLOPEN dlopen_ptr = NULL; - - if (!dlopen_ptr) { - dlopen_ptr = (PFN_DLOPEN)dlsym(RTLD_NEXT, "dlopen"); - if (!dlopen_ptr) { - os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n"); - return NULL; - } - } - - return dlopen_ptr(filename, flag); -} - /* * Several applications, such as Quake3, use dlopen("libGL.so.1"), but @@ -174,7 +149,7 @@ void * dlopen(const char *filename, int flag) { bool intercept = false; - if (filename) { + if (filename && trace::isTracingEnabled()) { intercept = strcmp(filename, "libEGL.so") == 0 || strcmp(filename, "libEGL.so.1") == 0 || @@ -216,9 +191,6 @@ void * dlopen(const char *filename, int flag) } -#endif /* !ANDROID */ - - #if defined(ANDROID) /*