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