glapi_getproc.c revision 1eee1bac1f6d911e6124daafc9b9291666d91cef
1a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/* 2a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Mesa 3-D graphics library 3a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Version: 7.1 4a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 5a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 7a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 8a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * copy of this software and associated documentation files (the "Software"), 9a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to deal in the Software without restriction, including without limitation 10a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 12a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Software is furnished to do so, subject to the following conditions: 13a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 14a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The above copyright notice and this permission notice shall be included 15a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in all copies or substantial portions of the Software. 16a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 17a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 24a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 25a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 261eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee * \file glapi_getproc.c 27a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 28a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Code for implementing glXGetProcAddress(), etc. 29a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This was originally in glapi.c but refactored out. 30a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 31a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 32a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 33a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include <stdlib.h> 34a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include <string.h> 358e7d941d7a29aaf66f94892b3f97670c0e972c8cKeith Whitwell#include "main/glheader.h" 36f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "main/compiler.h" 37a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include "glapi.h" 38a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include "glapioffsets.h" 39a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include "glapitable.h" 40a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 41a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 42c79779aff09073d87b9a6138bf09f23c3b8b5fd7Brian Paulstatic void 43c79779aff09073d87b9a6138bf09f23c3b8b5fd7Brian Paulfill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset); 44c79779aff09073d87b9a6138bf09f23c3b8b5fd7Brian Paul 45c79779aff09073d87b9a6138bf09f23c3b8b5fd7Brian Paul 46a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 47a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * strdup() is actually not a standard ANSI C or POSIX routine. 48a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Irix will not define it if ANSI mode is in effect. 49a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 50a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic char * 51a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstr_dup(const char *str) 52a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 53a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul char *copy; 54a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul copy = (char*) malloc(strlen(str) + 1); 55a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (!copy) 56a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 57a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul strcpy(copy, str); 58a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return copy; 59a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 60a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 61a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 62a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 63a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS) 64a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define DISPATCH_FUNCTION_SIZE 16 65a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(USE_X86_ASM) 66a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# if defined(THREADS) && !defined(GLX_USE_TLS) 67a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define DISPATCH_FUNCTION_SIZE 32 68a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# else 69a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define DISPATCH_FUNCTION_SIZE 16 70a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# endif 71a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 72a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 73a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer) 74a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# define NEED_FUNCTION_POINTER 75a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 76a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 77a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/* The code in this file is auto-generated with Python */ 78a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#include "glprocs.h" 79a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 80a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 81a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 82a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Search the table of static entrypoint functions for the named function 83a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * and return the corresponding glprocs_table_t entry. 84a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 85a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const glprocs_table_t * 86a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulfind_entry( const char * n ) 87a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 88a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 89a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 90a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char *testName = gl_string_table + static_functions[i].Name_offset; 914447fddc82a2c0245e798c90492293d875d186d0Brian Paul#ifdef MANGLE 924447fddc82a2c0245e798c90492293d875d186d0Brian Paul /* skip the "m" prefix on the name */ 934447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n + 1) == 0) 944447fddc82a2c0245e798c90492293d875d186d0Brian Paul#else 954447fddc82a2c0245e798c90492293d875d186d0Brian Paul if (strcmp(testName, n) == 0) 964447fddc82a2c0245e798c90492293d875d186d0Brian Paul#endif 974447fddc82a2c0245e798c90492293d875d186d0Brian Paul { 98a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return &static_functions[i]; 99a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 100a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 101a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 102a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 103a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 104a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 105a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 106a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch table offset of the named static (built-in) function. 107a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return -1 if function not found. 108a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 109a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLint 110a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_offset(const char *funcName) 111a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 112a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const glprocs_table_t * const f = find_entry( funcName ); 113a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (f) { 114a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return f->Offset; 115a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 116a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 117a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 118a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 119a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 120a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if !defined(XFree86Server) && !defined(XGLServer) 121a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef USE_X86_ASM 122a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 123a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined( GLX_USE_TLS ) 124a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulextern GLubyte gl_dispatch_functions_start[]; 125a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulextern GLubyte gl_dispatch_functions_end[]; 126a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 127a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulextern const GLubyte gl_dispatch_functions_start[]; 128a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 129a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 130a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* USE_X86_ASM */ 131a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 132a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 133a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 134a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return dispatch function address for the named static (built-in) function. 135a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return NULL if function not found. 136a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 137a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic _glapi_proc 138a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_address(const char *funcName) 139a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 140a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const glprocs_table_t * const f = find_entry( funcName ); 141a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (f) { 142a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING) 143a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (f->Address == NULL) 144a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ? (_glapi_proc) (gl_dispatch_functions_start 145a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul + (DISPATCH_FUNCTION_SIZE * f->Offset)) 146a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul : f->Address; 147a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(DISPATCH_FUNCTION_SIZE) 148a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (_glapi_proc) (gl_dispatch_functions_start 149a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul + (DISPATCH_FUNCTION_SIZE * f->Offset)); 150a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 151a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return f->Address; 152a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 153a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 154a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul else { 155a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 156a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 157a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 158a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 159a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* !defined(XFree86Server) && !defined(XGLServer) */ 160a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 161a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 162a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 163a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 164a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given offset in the dispatch 165a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * table. For debugging only. 166a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 167a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic const char * 168a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulget_static_proc_name( GLuint offset ) 169a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 170a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 171a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; static_functions[i].Name_offset >= 0; i++) { 172a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (static_functions[i].Offset == offset) { 173a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return gl_string_table + static_functions[i].Name_offset; 174a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 175a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 176a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 177a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 178a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 179a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 180a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 181a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/********************************************************************** 182a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Extension function management. 183a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 184a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 185a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 186a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 187a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Track information about a function added to the GL API. 188a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 189a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstruct _glapi_function { 190a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 191a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Name of the function. 192a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 193a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * name; 194a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 195a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 196a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 197a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Text string that describes the types of the parameters passed to the 198a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * named function. Parameter types are converted to characters using the 199a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * following rules: 200a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 201a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 202a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 203a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 204a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 205a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature; 206a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 207a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 208a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 209a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Offset in the dispatch table where the pointer to the real function is 210a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * located. If the driver has not requested that the named function be 211a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * added to the dispatch table, this will have the value ~0. 212a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 213a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned dispatch_offset; 214a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 215a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 216a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /** 217a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Pointer to the dispatch stub for the named function. 218a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 219a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 220a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The semantic of this field should be changed slightly. Currently, it 221a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * is always expected to be non-\c NULL. However, it would be better to 222a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * only allocate the entry-point stub when the application requests the 223a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * function via \c glXGetProcAddress. This would save memory for all the 224a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * functions that the driver exports but that the application never wants 225a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * to call. 226a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 227a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc dispatch_stub; 228a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul}; 229a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 230a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 231a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS]; 232a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic GLuint NumExtEntryPoints = 0; 233a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 234a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef USE_SPARC_ASM 235a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulextern void __glapi_sparc_icache_flush(unsigned int *); 236a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 237a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 238a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 239a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Generate a dispatch function (entrypoint) which jumps through 240a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the given slot number (offset) in the current dispatch table. 241a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * We need assembly language in order to accomplish this. 242a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 243a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic _glapi_proc 244a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulgenerate_entrypoint(GLuint functionOffset) 245a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 246a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(USE_X86_ASM) 247a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* 32 is chosen as something of a magic offset. For x86, the dispatch 248a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * at offset 32 is the first one where the offset in the 249a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * "jmp OFFSET*4(%eax)" can't be encoded in a single byte. 250a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 251a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const GLubyte * const template_func = gl_dispatch_functions_start 252a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul + (DISPATCH_FUNCTION_SIZE * 32); 253a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLubyte * const code = (GLubyte *) malloc(DISPATCH_FUNCTION_SIZE); 254a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 255a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 256a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( code != NULL ) { 257a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memcpy(code, template_func, DISPATCH_FUNCTION_SIZE); 258a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul fill_in_entrypoint_offset( (_glapi_proc) code, functionOffset ); 259a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 260a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 261a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (_glapi_proc) code; 262857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller#elif defined(USE_SPARC_ASM) && (defined(PTHREADS) || defined(GLX_USE_TLS)) 263857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller static const unsigned int template[] = { 264857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller 0x07000000, /* sethi %hi(0), %g3 */ 265857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller 0x8210000f, /* mov %o7, %g1 */ 266857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller 0x40000000, /* call */ 267857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller 0x9e100001, /* mov %g1, %o7 */ 268a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul }; 269857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller#ifdef GLX_USE_TLS 270857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller extern unsigned int __glapi_sparc_tls_stub; 271857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller unsigned long call_dest = (unsigned long ) &__glapi_sparc_tls_stub; 272a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 273857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller extern unsigned int __glapi_sparc_pthread_stub; 274857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller unsigned long call_dest = (unsigned long ) &__glapi_sparc_pthread_stub; 275857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller#endif 276857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller unsigned int *code = (unsigned int *) malloc(sizeof(template)); 277a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (code) { 278857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[0] = template[0] | (functionOffset & 0x3fffff); 279857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[1] = template[1]; 280a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul __glapi_sparc_icache_flush(&code[0]); 281857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[2] = template[2] | 282857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller (((call_dest - ((unsigned long) &code[2])) 283857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller >> 2) & 0x3fffffff); 284857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[3] = template[3]; 285a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul __glapi_sparc_icache_flush(&code[2]); 286a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 287a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (_glapi_proc) code; 288a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 289a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) functionOffset; 290a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 291a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* USE_*_ASM */ 292a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 293a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 294a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 295a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 296a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function inserts a new dispatch offset into the assembly language 297a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * stub that was generated with the preceeding function. 298a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 299a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic void 300a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulfill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset) 301a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 302a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if defined(USE_X86_ASM) 303a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLubyte * const code = (GLubyte *) entrypoint; 304a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 305a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if DISPATCH_FUNCTION_SIZE == 32 306a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul *((unsigned int *)(code + 11)) = 4 * offset; 307a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul *((unsigned int *)(code + 22)) = 4 * offset; 308a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS ) 309a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul *((unsigned int *)(code + 8)) = 4 * offset; 310a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif DISPATCH_FUNCTION_SIZE == 16 311a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul *((unsigned int *)(code + 7)) = 4 * offset; 312a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 313a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul# error Invalid DISPATCH_FUNCTION_SIZE! 314a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 315a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 316a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#elif defined(USE_SPARC_ASM) 317a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned int *code = (unsigned int *) entrypoint; 318857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[0] &= ~0x3fffff; 319857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller code[0] |= (offset * sizeof(void *)) & 0x3fffff; 320857ac1e817808f4b6bf985679162d0e3d709e5b5David S. Miller __glapi_sparc_icache_flush(&code[0]); 321a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 322a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 323a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* an unimplemented architecture */ 324a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) entrypoint; 325a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) offset; 326a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 327a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* USE_*_ASM */ 328a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 329a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 330a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 331a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 332a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Generate new entrypoint 333a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 334a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver 335a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * calls \c _glapi_add_dispatch we'll put in the proper offset. If that 336a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * never happens, and the user calls this function, he'll segfault. That's 337a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * what you get when you try calling a GL function that doesn't really exist. 338a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 339a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param funcName Name of the function to create an entry-point for. 340a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 341a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa _glapi_add_entrypoint 342a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 343a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 344a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulstatic struct _glapi_function * 345a97226352fb8063d4d0084523312b4880dae5ac7Brian Pauladd_function_name( const char * funcName ) 346a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 347a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry = NULL; 348a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 349a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) { 350a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul _glapi_proc entrypoint = generate_entrypoint(~0); 351a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entrypoint != NULL) { 352a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = & ExtEntryTable[NumExtEntryPoints]; 353a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 354a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].name = str_dup(funcName); 355a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL; 356a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0; 357a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ExtEntryTable[NumExtEntryPoints].dispatch_stub = entrypoint; 358a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul NumExtEntryPoints++; 359a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 360a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 361a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 362a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return entry; 363a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 364a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 365a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 366a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 367a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Fill-in the dispatch stub for the named function. 368a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 369a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function is intended to be called by a hardware driver. When called, 370a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a dispatch stub may be created created for the function. A pointer to this 371a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * dispatch function will be returned by glXGetProcAddress. 372a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 373a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param function_names Array of pointers to function names that should 374a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * share a common dispatch offset. 375a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \param parameter_signature String representing the types of the parameters 376a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * passed to the named function. Parameter types 377a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * are converted to characters using the following 378a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * rules: 379a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'i' for \c GLint, \c GLuint, and \c GLenum 380a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'p' for any pointer type 381a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'f' for \c GLfloat and \c GLclampf 382a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * - 'd' for \c GLdouble and \c GLclampd 383a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 384a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \returns 385a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * The offset in the dispatch table of the named function. A pointer to the 386a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * driver's implementation of the named function should be stored at 387a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c dispatch_table[\c offset]. Return -1 if error/problem. 388a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 389a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \sa glXGetProcAddress 390a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 391a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \warning 392a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This function can only handle up to 8 names at a time. As far as I know, 393a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the maximum number of names ever associated with an existing GL function is 394a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT, 395a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c glPointParameterfARB, and \c glPointParameterf), so this should not be 396a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * too painful of a limitation. 397a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 398a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 399a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine whether or not \c parameter_signature should be allowed to be 400a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \c NULL. It doesn't seem like much of a hardship for drivers to have to 401a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * pass in an empty string. 402a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 403a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \todo 404a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Determine if code should be added to reject function names that start with 405a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 'glX'. 406a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * 407a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * \bug 408a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Add code to compare \c parameter_signature with the parameter signature of 409a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * a static function. In order to do that, we need to find a way to \b get 410a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the parameter signature of a static function. 411a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 412a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 413a97226352fb8063d4d0084523312b4880dae5ac7Brian PaulPUBLIC int 414a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_add_dispatch( const char * const * function_names, 415a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * parameter_signature ) 416a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 417a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC; 418a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * const real_sig = (parameter_signature != NULL) 419a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul ? parameter_signature : ""; 420a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry[8]; 421a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLboolean is_static[8]; 422a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned i; 423a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul unsigned j; 424a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int offset = ~0; 425a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul int new_offset; 426a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 427a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 428a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( is_static, 0, sizeof( is_static ) ); 429a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul (void) memset( entry, 0, sizeof( entry ) ); 430a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 431a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 432a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* Do some trivial validation on the name of the function. 433a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 434a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 435a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l') 436a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 437a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 438a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* Determine if the named function already exists. If the function does 439a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * exist, it must have the same parameter signature as the function 440a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * being added. 441a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 442a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 443a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul new_offset = get_static_proc_offset(function_names[i]); 444a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (new_offset >= 0) { 445a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Make sure the parameter signatures match! How do we get 446a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * FIXME: the parameter signature for static functions? 447a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 448a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 449a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( (offset != ~0) && (new_offset != offset) ) { 450a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 451a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 452a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 453a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul is_static[i] = GL_TRUE; 454a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = new_offset; 455a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 456a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 457a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 458a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( j = 0 ; j < NumExtEntryPoints ; j++ ) { 459a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) { 460a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* The offset may be ~0 if the function name was added by 461a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * glXGetProcAddress but never filled in by the driver. 462a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 463a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 464a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (ExtEntryTable[j].dispatch_offset != ~0) { 465a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) 466a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul != 0) { 467a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 468a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 469a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 470a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( (offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset) ) { 471a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 472a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 473a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 474a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = ExtEntryTable[j].dispatch_offset; 475a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 476a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 477a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i] = & ExtEntryTable[j]; 478a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul break; 479a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 480a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 481a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 482a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 483a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (offset == ~0) { 484a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul offset = next_dynamic_offset; 485a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul next_dynamic_offset++; 486a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 487a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 488a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for ( i = 0 ; function_names[i] != NULL ; i++ ) { 489a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (! is_static[i] ) { 490a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 491a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i] = add_function_name( function_names[i] ); 492a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (entry[i] == NULL) { 493a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* FIXME: Possible memory leak here. 494a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 495a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return -1; 496a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 497a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 498a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 499a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i]->parameter_signature = str_dup(real_sig); 500a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset); 501a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry[i]->dispatch_offset = offset; 502a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 503a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 504a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 505a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return offset; 506a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 507a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 508a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 509a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 510a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return offset of entrypoint for named function within dispatch table. 511a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 512a97226352fb8063d4d0084523312b4880dae5ac7Brian PaulPUBLIC GLint 513a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_offset(const char *funcName) 514a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 515a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 516a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 517a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; i < NumExtEntryPoints; i++) { 518a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(ExtEntryTable[i].name, funcName) == 0) { 519a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return ExtEntryTable[i].dispatch_offset; 520a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 521a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 522a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 523a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return get_static_proc_offset(funcName); 524a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 525a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 526a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 527a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 528a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 529a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return pointer to the named function. If the function name isn't found 530a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * in the name of static functions, try generating a new API entrypoint on 531a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * the fly with assembly language. 532a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 533a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_proc 534a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_address(const char *funcName) 535a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 536a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul struct _glapi_function * entry; 537a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 538a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 539a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#ifdef MANGLE 540a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (funcName[0] != 'm' || funcName[1] != 'g' || funcName[2] != 'l') 541a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 542a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#else 543a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (funcName[0] != 'g' || funcName[1] != 'l') 544a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 545a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif 546a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 547a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search extension functions first */ 548a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; i < NumExtEntryPoints; i++) { 549a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (strcmp(ExtEntryTable[i].name, funcName) == 0) { 550a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return ExtEntryTable[i].dispatch_stub; 551a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 552a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 553a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 554a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#if !defined( XFree86Server ) && !defined( XGLServer ) 555a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search static functions */ 556a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul { 557a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const _glapi_proc func = get_static_proc_address(funcName); 558a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (func) 559a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return func; 560a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 561a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul#endif /* !defined( XFree86Server ) */ 562a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 563a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul entry = add_function_name(funcName); 564a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return (entry == NULL) ? NULL : entry->dispatch_stub; 565a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 566a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 567a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 568a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 569a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul/** 570a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * Return the name of the function at the given dispatch offset. 571a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul * This is only intended for debugging. 572a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul */ 573a97226352fb8063d4d0084523312b4880dae5ac7Brian Paulconst char * 574a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul_glapi_get_proc_name(GLuint offset) 575a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul{ 576a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul GLuint i; 577a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul const char * n; 578a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 579a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search built-in functions */ 580a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul n = get_static_proc_name(offset); 581a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if ( n != NULL ) { 582a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return n; 583a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 584a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul 585a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul /* search added extension functions */ 586a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul for (i = 0; i < NumExtEntryPoints; i++) { 587a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul if (ExtEntryTable[i].dispatch_offset == offset) { 588a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return ExtEntryTable[i].name; 589a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 590a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul } 591a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul return NULL; 592a97226352fb8063d4d0084523312b4880dae5ac7Brian Paul} 593