1848b8605Smrg 2848b8605Smrg# (C) Copyright IBM Corporation 2004, 2005 3848b8605Smrg# (C) Copyright Apple Inc. 2011 4b8e80941Smrg# Copyright (C) 2015 Intel Corporation 5848b8605Smrg# All Rights Reserved. 6848b8605Smrg# 7848b8605Smrg# Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg# copy of this software and associated documentation files (the "Software"), 9848b8605Smrg# to deal in the Software without restriction, including without limitation 10848b8605Smrg# on the rights to use, copy, modify, merge, publish, distribute, sub 11848b8605Smrg# license, and/or sell copies of the Software, and to permit persons to whom 12848b8605Smrg# the Software is furnished to do so, subject to the following conditions: 13848b8605Smrg# 14848b8605Smrg# The above copyright notice and this permission notice (including the next 15848b8605Smrg# paragraph) shall be included in all copies or substantial portions of the 16848b8605Smrg# Software. 17848b8605Smrg# 18848b8605Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19848b8605Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20848b8605Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21848b8605Smrg# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22848b8605Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23848b8605Smrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24848b8605Smrg# IN THE SOFTWARE. 25848b8605Smrg# 26848b8605Smrg# Authors: 27848b8605Smrg# Jeremy Huddleston <jeremyhu@apple.com> 28848b8605Smrg# 29848b8605Smrg# Based on code ogiginally by: 30848b8605Smrg# Ian Romanick <idr@us.ibm.com> 31848b8605Smrg 32b8e80941Smrgfrom __future__ import print_function 33b8e80941Smrg 34b8e80941Smrgimport argparse 35b8e80941Smrg 36848b8605Smrgimport license 37848b8605Smrgimport gl_XML, glX_XML 38848b8605Smrg 39848b8605Smrgheader = """/* GLXEXT is the define used in the xserver when the GLX extension is being 40848b8605Smrg * built. Hijack this to determine whether this file is being built for the 41848b8605Smrg * server or the client. 42848b8605Smrg */ 43848b8605Smrg#ifdef HAVE_DIX_CONFIG_H 44848b8605Smrg#include <dix-config.h> 45848b8605Smrg#endif 46848b8605Smrg 47848b8605Smrg#if (defined(GLXEXT) && defined(HAVE_BACKTRACE)) \\ 48b8e80941Smrg || (!defined(GLXEXT) && defined(DEBUG) && defined(HAVE_EXECINFO_H)) 49848b8605Smrg#define USE_BACKTRACE 50848b8605Smrg#endif 51848b8605Smrg 52848b8605Smrg#ifdef USE_BACKTRACE 53848b8605Smrg#include <execinfo.h> 54848b8605Smrg#endif 55848b8605Smrg 56848b8605Smrg#ifndef _WIN32 57848b8605Smrg#include <dlfcn.h> 58848b8605Smrg#endif 59848b8605Smrg#include <stdlib.h> 60848b8605Smrg#include <stdio.h> 61b8e80941Smrg#include <string.h> 62848b8605Smrg 63848b8605Smrg#include "main/glheader.h" 64848b8605Smrg 65848b8605Smrg#include "glapi.h" 66848b8605Smrg#include "glapitable.h" 67848b8605Smrg 68848b8605Smrg#ifdef GLXEXT 69848b8605Smrg#include "os.h" 70848b8605Smrg#endif 71848b8605Smrg 72848b8605Smrgstatic void 73848b8605Smrg__glapi_gentable_NoOp(void) { 74848b8605Smrg const char *fstr = "Unknown"; 75848b8605Smrg 76848b8605Smrg /* Silence potential GCC warning for some #ifdef paths. 77848b8605Smrg */ 78848b8605Smrg (void) fstr; 79848b8605Smrg#if defined(USE_BACKTRACE) 80848b8605Smrg#if !defined(GLXEXT) 81848b8605Smrg if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) 82848b8605Smrg#endif 83848b8605Smrg { 84848b8605Smrg void *frames[2]; 85848b8605Smrg 86848b8605Smrg if(backtrace(frames, 2) == 2) { 87848b8605Smrg Dl_info info; 88848b8605Smrg dladdr(frames[1], &info); 89848b8605Smrg if(info.dli_sname) 90848b8605Smrg fstr = info.dli_sname; 91848b8605Smrg } 92848b8605Smrg 93848b8605Smrg#if !defined(GLXEXT) 94848b8605Smrg fprintf(stderr, "Call to unimplemented API: %s\\n", fstr); 95848b8605Smrg#endif 96848b8605Smrg } 97848b8605Smrg#endif 98848b8605Smrg#if defined(GLXEXT) 99848b8605Smrg LogMessage(X_ERROR, "GLX: Call to unimplemented API: %s\\n", fstr); 100848b8605Smrg#endif 101848b8605Smrg} 102848b8605Smrg 103848b8605Smrgstatic void 104848b8605Smrg__glapi_gentable_set_remaining_noop(struct _glapi_table *disp) { 105848b8605Smrg GLuint entries = _glapi_get_dispatch_table_size(); 106848b8605Smrg void **dispatch = (void **) disp; 107b8e80941Smrg unsigned i; 108848b8605Smrg 109848b8605Smrg /* ISO C is annoying sometimes */ 110848b8605Smrg union {_glapi_proc p; void *v;} p; 111848b8605Smrg p.p = __glapi_gentable_NoOp; 112848b8605Smrg 113848b8605Smrg for(i=0; i < entries; i++) 114848b8605Smrg if(dispatch[i] == NULL) 115848b8605Smrg dispatch[i] = p.v; 116848b8605Smrg} 117848b8605Smrg 118b8e80941Smrg""" 119b8e80941Smrg 120b8e80941Smrgfooter = """ 121848b8605Smrgstruct _glapi_table * 122848b8605Smrg_glapi_create_table_from_handle(void *handle, const char *symbol_prefix) { 123b8e80941Smrg struct _glapi_table *disp = calloc(_glapi_get_dispatch_table_size(), sizeof(_glapi_proc)); 124848b8605Smrg char symboln[512]; 125848b8605Smrg 126848b8605Smrg if(!disp) 127848b8605Smrg return NULL; 128848b8605Smrg 129848b8605Smrg if(symbol_prefix == NULL) 130848b8605Smrg symbol_prefix = ""; 131848b8605Smrg 132b8e80941Smrg /* Note: This code relies on _glapi_table_func_names being sorted by the 133b8e80941Smrg * entry point index of each function. 134b8e80941Smrg */ 135b8e80941Smrg for (int func_index = 0; func_index < GLAPI_TABLE_COUNT; ++func_index) { 136b8e80941Smrg const char *name = _glapi_table_func_names[func_index]; 137b8e80941Smrg void ** procp = &((void **)disp)[func_index]; 138848b8605Smrg 139b8e80941Smrg snprintf(symboln, sizeof(symboln), \"%s%s\", symbol_prefix, name); 140848b8605Smrg#ifdef _WIN32 141848b8605Smrg *procp = GetProcAddress(handle, symboln); 142848b8605Smrg#else 143848b8605Smrg *procp = dlsym(handle, symboln); 144848b8605Smrg#endif 145848b8605Smrg } 146b8e80941Smrg __glapi_gentable_set_remaining_noop(disp); 147b8e80941Smrg 148b8e80941Smrg return disp; 149b8e80941Smrg} 150b8e80941Smrg 151b8e80941Smrgvoid 152b8e80941Smrg _glapi_table_patch(struct _glapi_table *table, const char *name, void *wrapper) 153b8e80941Smrg{ 154b8e80941Smrg for (int func_index = 0; func_index < GLAPI_TABLE_COUNT; ++func_index) { 155b8e80941Smrg if (!strcmp(_glapi_table_func_names[func_index], name)) { 156b8e80941Smrg ((void **)table)[func_index] = wrapper; 157b8e80941Smrg return; 158b8e80941Smrg } 159b8e80941Smrg } 160b8e80941Smrg fprintf(stderr, "could not patch %s in dispatch table\\n", name); 161b8e80941Smrg} 162b8e80941Smrg 163848b8605Smrg""" 164848b8605Smrg 165b8e80941Smrg 166848b8605Smrgclass PrintCode(gl_XML.gl_print_base): 167848b8605Smrg 168848b8605Smrg def __init__(self): 169848b8605Smrg gl_XML.gl_print_base.__init__(self) 170848b8605Smrg 171b8e80941Smrg self.name = "gl_gentable.py (from Mesa)" 172848b8605Smrg self.license = license.bsd_license_template % ( \ 173848b8605Smrg"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 174848b8605Smrg(C) Copyright IBM Corporation 2004, 2005 175848b8605Smrg(C) Copyright Apple Inc 2011""", "BRIAN PAUL, IBM") 176848b8605Smrg 177848b8605Smrg return 178848b8605Smrg 179848b8605Smrg 180848b8605Smrg def get_stack_size(self, f): 181848b8605Smrg size = 0 182848b8605Smrg for p in f.parameterIterator(): 183848b8605Smrg if p.is_padding: 184848b8605Smrg continue 185848b8605Smrg 186848b8605Smrg size += p.get_stack_size() 187848b8605Smrg 188848b8605Smrg return size 189848b8605Smrg 190848b8605Smrg 191848b8605Smrg def printRealHeader(self): 192b8e80941Smrg print(header) 193848b8605Smrg return 194848b8605Smrg 195848b8605Smrg 196848b8605Smrg def printRealFooter(self): 197b8e80941Smrg print(footer) 198848b8605Smrg return 199848b8605Smrg 200848b8605Smrg 201848b8605Smrg def printBody(self, api): 202848b8605Smrg 203b8e80941Smrg # Determine how many functions have a defined offset. 204b8e80941Smrg func_count = 0 205b8e80941Smrg for f in api.functions_by_name.values(): 206b8e80941Smrg if f.offset != -1: 207b8e80941Smrg func_count += 1 208b8e80941Smrg 209b8e80941Smrg # Build the mapping from offset to function name. 210b8e80941Smrg funcnames = [None] * func_count 211b8e80941Smrg for f in api.functions_by_name.values(): 212b8e80941Smrg if f.offset != -1: 213b8e80941Smrg if not (funcnames[f.offset] is None): 214b8e80941Smrg raise Exception("Function table has more than one function with same offset (offset %d, func %s)" % (f.offset, f.name)) 215b8e80941Smrg funcnames[f.offset] = f.name 216b8e80941Smrg 217b8e80941Smrg # Check that the table has no gaps. We expect a function at every offset, 218b8e80941Smrg # and the code which generates the table relies on this. 219b8e80941Smrg for i in range(0, func_count): 220b8e80941Smrg if funcnames[i] is None: 221b8e80941Smrg raise Exception("Function table has no function at offset %d" % (i)) 222b8e80941Smrg 223b8e80941Smrg print("#define GLAPI_TABLE_COUNT %d" % func_count) 224b8e80941Smrg print("static const char * const _glapi_table_func_names[GLAPI_TABLE_COUNT] = {") 225b8e80941Smrg for i in range(0, func_count): 226b8e80941Smrg print(" /* %5d */ \"%s\"," % (i, funcnames[i])) 227b8e80941Smrg print("};") 228b8e80941Smrg 229848b8605Smrg return 230848b8605Smrg 231848b8605Smrg 232b8e80941Smrgdef _parser(): 233b8e80941Smrg """Parse arguments and return a namespace object.""" 234b8e80941Smrg parser = argparse.ArgumentParser() 235b8e80941Smrg parser.add_argument('-f', 236b8e80941Smrg dest='filename', 237b8e80941Smrg default='gl_API.xml', 238b8e80941Smrg help='An XML file description of an API') 239b8e80941Smrg 240b8e80941Smrg return parser.parse_args() 241848b8605Smrg 242848b8605Smrg 243b8e80941Smrgdef main(): 244b8e80941Smrg """Main function.""" 245b8e80941Smrg args = _parser() 246848b8605Smrg 247848b8605Smrg printer = PrintCode() 248848b8605Smrg 249b8e80941Smrg api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory()) 250848b8605Smrg printer.Print(api) 251b8e80941Smrg 252b8e80941Smrg 253b8e80941Smrgif __name__ == '__main__': 254b8e80941Smrg main() 255