]> git.cworth.org Git - apitrace/blob - wrappers/glxtrace.py
e4d05180e15b4dd06d4ffe2f11dbf77fe0d80a29
[apitrace] / wrappers / glxtrace.py
1 ##########################################################################
2 #
3 # Copyright 2011 Jose Fonseca
4 # Copyright 2008-2010 VMware, Inc.
5 # All Rights Reserved.
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 # THE SOFTWARE.
24 #
25 ##########################################################################/
26
27
28 """GLX tracing generator."""
29
30
31 from gltrace import GlTracer
32 from specs.stdapi import API
33 from specs.glapi import glapi
34 from specs.glxapi import glxapi
35
36
37 class GlxTracer(GlTracer):
38
39     def isFunctionPublic(self, function):
40         # The symbols visible in libGL.so can vary, so expose them all
41         return True
42
43     getProcAddressFunctionNames = [
44         "glXGetProcAddress",
45         "glXGetProcAddressARB",
46     ]
47
48
49 if __name__ == '__main__':
50     print
51     print '#include <stdlib.h>'
52     print '#include <string.h>'
53     print
54     print '#ifndef _GNU_SOURCE'
55     print '#define _GNU_SOURCE // for dladdr'
56     print '#endif'
57     print '#include <dlfcn.h>'
58     print
59     print '#include "trace_writer_local.hpp"'
60     print
61     print '// To validate our prototypes'
62     print '#define GL_GLEXT_PROTOTYPES'
63     print '#define GLX_GLXEXT_PROTOTYPES'
64     print
65     print '#include "glproc.hpp"'
66     print '#include "glsize.hpp"'
67     print
68
69     api = API()
70     api.addApi(glxapi)
71     api.addApi(glapi)
72     tracer = GlxTracer()
73     tracer.traceApi(api)
74
75     print r'''
76
77
78 /*
79  * Invoke the true dlopen() function.
80  */
81 static void *__dlopen(const char *filename, int flag)
82 {
83     typedef void * (*PFNDLOPEN)(const char *, int);
84     static PFNDLOPEN dlopen_ptr = NULL;
85
86     if (!dlopen_ptr) {
87         dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen");
88         if (!dlopen_ptr) {
89             os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n");
90             return NULL;
91         }
92     }
93
94     return dlopen_ptr(filename, flag);
95 }
96
97
98 /*
99  * Several applications, such as Quake3, use dlopen("libGL.so.1"), but
100  * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore
101  * we need to intercept the dlopen() call here, and redirect to our wrapper
102  * shared object.
103  */
104 extern "C" PUBLIC
105 void * dlopen(const char *filename, int flag)
106 {
107     void *handle;
108
109     handle = __dlopen(filename, flag);
110
111     const char * libgl_filename = getenv("TRACE_LIBGL");
112
113     if (filename && handle && !libgl_filename) {
114         if (0) {
115             os::log("apitrace: warning: dlopen(\"%s\", 0x%x)\n", filename, flag);
116         }
117
118         // FIXME: handle absolute paths and other versions
119         if (strcmp(filename, "libGL.so") == 0 ||
120             strcmp(filename, "libGL.so.1") == 0) {
121
122             // Use the true libGL.so handle instead of RTLD_NEXT from now on
123             __libGlHandle = handle;
124
125             // Get the file path for our shared object, and use it instead
126             static int dummy = 0xdeedbeef;
127             Dl_info info;
128             if (dladdr(&dummy, &info)) {
129                 os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
130                 handle = __dlopen(info.dli_fname, flag);
131             } else {
132                 os::log("apitrace: warning: dladdr() failed\n");
133             }
134         }
135     }
136
137     return handle;
138 }
139
140
141
142 '''