]> git.cworth.org Git - apitrace/commitdiff
Implement interposing of dlopen on Android
authorAlexander Monakov <amonakov@ispras.ru>
Fri, 3 May 2013 17:03:27 +0000 (21:03 +0400)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 4 May 2013 08:37:50 +0000 (09:37 +0100)
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 <jose.r.fonseca@gmail.com>
dispatch/dlopen.hpp [new file with mode: 0644]
dispatch/glproc_egl.cpp
dispatch/glproc_gl.cpp
wrappers/egltrace.py

diff --git a/dispatch/dlopen.hpp b/dispatch/dlopen.hpp
new file mode 100644 (file)
index 0000000..cb59a44
--- /dev/null
@@ -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 <dlfcn.h>
+
+#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_ */
index c77c444b8d7ff3dc8cb5b97b573c20520f146398..abba72755ceed5962a7b318d3b2c8bc941ef1a7d 100644 (file)
@@ -28,7 +28,7 @@
 
 
 #if !defined(_WIN32)
-#include <dlfcn.h>
+#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);
index 8e1216f1dc999c75f2cd16a751f4403b924868f6..1f3e9fc91016820d9b63244717c74d885f1ca7ac 100644 (file)
@@ -29,7 +29,7 @@
 
 #if !defined(_WIN32)
 #include <unistd.h> // for symlink
-#include <dlfcn.h>
+#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
  */
index 0c7ebb6b1937acedfd657d0bdabdc29e857b5947..8c4a46a0b9b3c5abde49ff91a936d4138f995285 100644 (file)
@@ -112,7 +112,7 @@ class EglTracer(GlTracer):
 if __name__ == '__main__':
     print '#include <stdlib.h>'
     print '#include <string.h>'
-    print '#include <dlfcn.h>'
+    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)
 
 /*