ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

glapi_getproc.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include "main/glheader.h"
00036 #include "glapi.h"
00037 #include "glapioffsets.h"
00038 #include "glapitable.h"
00039 
00040 
00041 static void
00042 fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset);
00043 
00044 
00049 static char *
00050 str_dup(const char *str)
00051 {
00052    char *copy;
00053    copy = (char*) malloc(strlen(str) + 1);
00054    if (!copy)
00055       return NULL;
00056    strcpy(copy, str);
00057    return copy;
00058 }
00059 
00060 
00061 
00062 #if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
00063 # define DISPATCH_FUNCTION_SIZE  16
00064 #elif defined(USE_X86_ASM)
00065 # if defined(THREADS) && !defined(GLX_USE_TLS)
00066 #  define DISPATCH_FUNCTION_SIZE  32
00067 # else
00068 #  define DISPATCH_FUNCTION_SIZE  16
00069 # endif
00070 #endif
00071 
00072 #if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer)
00073 # define NEED_FUNCTION_POINTER
00074 #endif
00075 
00076 /* The code in this file is auto-generated with Python */
00077 #include "glprocs.h"
00078 
00079 
00084 static const glprocs_table_t *
00085 find_entry( const char * n )
00086 {
00087    GLuint i;
00088    for (i = 0; static_functions[i].Name_offset >= 0; i++) {
00089       const char *testName = gl_string_table + static_functions[i].Name_offset;
00090 #ifdef MANGLE
00091       /* skip the "m" prefix on the name */
00092       if (strcmp(testName, n + 1) == 0)
00093 #else
00094       if (strcmp(testName, n) == 0)
00095 #endif
00096       {
00097      return &static_functions[i];
00098       }
00099    }
00100    return NULL;
00101 }
00102 
00103 
00108 static GLint
00109 get_static_proc_offset(const char *funcName)
00110 {
00111    const glprocs_table_t * const f = find_entry( funcName );
00112    if (f) {
00113       return f->Offset;
00114    }
00115    return -1;
00116 }
00117 
00118 
00119 #if !defined(XFree86Server) && !defined(XGLServer)
00120 #ifdef USE_X86_ASM
00121 
00122 #if defined( GLX_USE_TLS )
00123 extern       GLubyte gl_dispatch_functions_start[];
00124 extern       GLubyte gl_dispatch_functions_end[];
00125 #else
00126 extern const GLubyte gl_dispatch_functions_start[];
00127 #endif
00128 
00129 #endif /* USE_X86_ASM */
00130 
00131 
00136 static _glapi_proc
00137 get_static_proc_address(const char *funcName)
00138 {
00139    const glprocs_table_t * const f = find_entry( funcName );
00140    if (f) {
00141 #if defined(DISPATCH_FUNCTION_SIZE) && defined(GLX_INDIRECT_RENDERING)
00142       return (f->Address == NULL)
00143      ? (_glapi_proc) (gl_dispatch_functions_start
00144               + (DISPATCH_FUNCTION_SIZE * f->Offset))
00145          : f->Address;
00146 #elif defined(DISPATCH_FUNCTION_SIZE)
00147       return (_glapi_proc) (gl_dispatch_functions_start 
00148                             + (DISPATCH_FUNCTION_SIZE * f->Offset));
00149 #else
00150       return f->Address;
00151 #endif
00152    }
00153    else {
00154       return NULL;
00155    }
00156 }
00157 
00158 #endif /* !defined(XFree86Server) && !defined(XGLServer) */
00159 
00160 
00161 
00166 static const char *
00167 get_static_proc_name( GLuint offset )
00168 {
00169    GLuint i;
00170    for (i = 0; static_functions[i].Name_offset >= 0; i++) {
00171       if (static_functions[i].Offset == offset) {
00172      return gl_string_table + static_functions[i].Name_offset;
00173       }
00174    }
00175    return NULL;
00176 }
00177 
00178 
00179 
00180 /**********************************************************************
00181  * Extension function management.
00182  */
00183 
00184 
00188 struct _glapi_function {
00192    const char * name;
00193 
00194 
00204    const char * parameter_signature;
00205 
00206 
00212    unsigned dispatch_offset;
00213 
00214 
00226    _glapi_proc dispatch_stub;
00227 };
00228 
00229 
00230 static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS];
00231 static GLuint NumExtEntryPoints = 0;
00232 
00233 #ifdef USE_SPARC_ASM
00234 extern void __glapi_sparc_icache_flush(unsigned int *);
00235 #endif
00236 
00242 static _glapi_proc
00243 generate_entrypoint(GLuint functionOffset)
00244 {
00245 #if defined(USE_X86_ASM)
00246    /* 32 is chosen as something of a magic offset.  For x86, the dispatch
00247     * at offset 32 is the first one where the offset in the
00248     * "jmp OFFSET*4(%eax)" can't be encoded in a single byte.
00249     */
00250    const GLubyte * const template_func = gl_dispatch_functions_start 
00251      + (DISPATCH_FUNCTION_SIZE * 32);
00252    GLubyte * const code = (GLubyte *) malloc(DISPATCH_FUNCTION_SIZE);
00253 
00254 
00255    if ( code != NULL ) {
00256       (void) memcpy(code, template_func, DISPATCH_FUNCTION_SIZE);
00257       fill_in_entrypoint_offset( (_glapi_proc) code, functionOffset );
00258    }
00259 
00260    return (_glapi_proc) code;
00261 #elif defined(USE_SPARC_ASM)
00262 
00263 #ifdef __arch64__
00264    static const unsigned int insn_template[] = {
00265        0x05000000,  /* sethi    %uhi(_glapi_Dispatch), %g2  */
00266        0x03000000,  /* sethi    %hi(_glapi_Dispatch), %g1   */
00267        0x8410a000,  /* or       %g2, %ulo(_glapi_Dispatch), %g2 */
00268        0x82106000,  /* or       %g1, %lo(_glapi_Dispatch), %g1  */
00269        0x8528b020,  /* sllx     %g2, 32, %g2            */
00270        0xc2584002,  /* ldx      [%g1 + %g2], %g1        */
00271        0x05000000,  /* sethi    %hi(8 * glapioffset), %g2   */
00272        0x8410a000,  /* or       %g2, %lo(8 * glapioffset), %g2  */
00273        0xc6584002,  /* ldx      [%g1 + %g2], %g3        */
00274        0x81c0c000,  /* jmpl     %g3, %g0            */
00275        0x01000000   /*  nop                     */
00276    };
00277 #else
00278    static const unsigned int insn_template[] = {
00279        0x03000000,  /* sethi    %hi(_glapi_Dispatch), %g1     */
00280        0xc2006000,  /* ld       [%g1 + %lo(_glapi_Dispatch)], %g1 */
00281        0xc6006000,  /* ld       [%g1 + %lo(4*glapioffset)], %g3   */
00282        0x81c0c000,  /* jmpl     %g3, %g0              */
00283        0x01000000   /*  nop                       */
00284    };
00285 #endif /* __arch64__ */
00286    unsigned int *code = (unsigned int *) malloc(sizeof(insn_template));
00287    unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch;
00288    if (code) {
00289       memcpy(code, insn_template, sizeof(insn_template));
00290 
00291 #ifdef __arch64__
00292       code[0] |= (glapi_addr >> (32 + 10));
00293       code[1] |= ((glapi_addr & 0xffffffff) >> 10);
00294       __glapi_sparc_icache_flush(&code[0]);
00295       code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1));
00296       code[3] |= (glapi_addr & ((1 << 10) - 1));
00297       __glapi_sparc_icache_flush(&code[2]);
00298       code[6] |= ((functionOffset * 8) >> 10);
00299       code[7] |= ((functionOffset * 8) & ((1 << 10) - 1));
00300       __glapi_sparc_icache_flush(&code[6]);
00301 #else
00302       code[0] |= (glapi_addr >> 10);
00303       code[1] |= (glapi_addr & ((1 << 10) - 1));
00304       __glapi_sparc_icache_flush(&code[0]);
00305       code[2] |= (functionOffset * 4);
00306       __glapi_sparc_icache_flush(&code[2]);
00307 #endif /* __arch64__ */
00308    }
00309    return (_glapi_proc) code;
00310 #else
00311    (void) functionOffset;
00312    return NULL;
00313 #endif /* USE_*_ASM */
00314 }
00315 
00316 
00321 static void
00322 fill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset)
00323 {
00324 #if defined(USE_X86_ASM)
00325    GLubyte * const code = (GLubyte *) entrypoint;
00326 
00327 #if DISPATCH_FUNCTION_SIZE == 32
00328    *((unsigned int *)(code + 11)) = 4 * offset;
00329    *((unsigned int *)(code + 22)) = 4 * offset;
00330 #elif DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS )
00331    *((unsigned int *)(code +  8)) = 4 * offset;
00332 #elif DISPATCH_FUNCTION_SIZE == 16
00333    *((unsigned int *)(code +  7)) = 4 * offset;
00334 #else
00335 # error Invalid DISPATCH_FUNCTION_SIZE!
00336 #endif
00337 
00338 #elif defined(USE_SPARC_ASM)
00339 
00340    /* XXX this hasn't been tested! */
00341    unsigned int *code = (unsigned int *) entrypoint;
00342 #ifdef __arch64__
00343    code[6] = 0x05000000;  /* sethi  %hi(8 * glapioffset), %g2   */
00344    code[7] = 0x8410a000;  /* or     %g2, %lo(8 * glapioffset), %g2  */
00345    code[6] |= ((offset * 8) >> 10);
00346    code[7] |= ((offset * 8) & ((1 << 10) - 1));
00347    __glapi_sparc_icache_flush(&code[6]);
00348 #else /* __arch64__ */
00349    code[2] = 0xc6006000;  /* ld     [%g1 + %lo(4*glapioffset)], %g3   */
00350    code[2] |= (offset * 4);
00351    __glapi_sparc_icache_flush(&code[2]);
00352 #endif /* __arch64__ */
00353 
00354 #else
00355 
00356    /* an unimplemented architecture */
00357    (void) entrypoint;
00358    (void) offset;
00359 
00360 #endif /* USE_*_ASM */
00361 }
00362 
00363 
00377 static struct _glapi_function *
00378 add_function_name( const char * funcName )
00379 {
00380    struct _glapi_function * entry = NULL;
00381    
00382    if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) {
00383       _glapi_proc entrypoint = generate_entrypoint(~0);
00384       if (entrypoint != NULL) {
00385      entry = & ExtEntryTable[NumExtEntryPoints];
00386 
00387      ExtEntryTable[NumExtEntryPoints].name = str_dup(funcName);
00388      ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL;
00389      ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0;
00390      ExtEntryTable[NumExtEntryPoints].dispatch_stub = entrypoint;
00391      NumExtEntryPoints++;
00392       }
00393    }
00394 
00395    return entry;
00396 }
00397 
00398 
00446 PUBLIC int
00447 _glapi_add_dispatch( const char * const * function_names,
00448              const char * parameter_signature )
00449 {
00450    static int next_dynamic_offset = _gloffset_FIRST_DYNAMIC;
00451    const char * const real_sig = (parameter_signature != NULL)
00452      ? parameter_signature : "";
00453    struct _glapi_function * entry[8];
00454    GLboolean is_static[8];
00455    unsigned i;
00456    unsigned j;
00457    int offset = ~0;
00458    int new_offset;
00459 
00460 
00461    (void) memset( is_static, 0, sizeof( is_static ) );
00462    (void) memset( entry, 0, sizeof( entry ) );
00463 
00464    for ( i = 0 ; function_names[i] != NULL ; i++ ) {
00465       /* Do some trivial validation on the name of the function.
00466        */
00467 
00468       if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l')
00469          return -1;
00470    
00471       /* Determine if the named function already exists.  If the function does
00472        * exist, it must have the same parameter signature as the function
00473        * being added.
00474        */
00475 
00476       new_offset = get_static_proc_offset(function_names[i]);
00477       if (new_offset >= 0) {
00478      /* FIXME: Make sure the parameter signatures match!  How do we get
00479       * FIXME: the parameter signature for static functions?
00480       */
00481 
00482      if ( (offset != ~0) && (new_offset != offset) ) {
00483         return -1;
00484      }
00485 
00486      is_static[i] = GL_TRUE;
00487      offset = new_offset;
00488       }
00489    
00490    
00491       for ( j = 0 ; j < NumExtEntryPoints ; j++ ) {
00492      if (strcmp(ExtEntryTable[j].name, function_names[i]) == 0) {
00493         /* The offset may be ~0 if the function name was added by
00494          * glXGetProcAddress but never filled in by the driver.
00495          */
00496 
00497         if (ExtEntryTable[j].dispatch_offset != ~0) {
00498            if (strcmp(real_sig, ExtEntryTable[j].parameter_signature) 
00499            != 0) {
00500           return -1;
00501            }
00502 
00503            if ( (offset != ~0) && (ExtEntryTable[j].dispatch_offset != offset) ) {
00504           return -1;
00505            }
00506 
00507            offset = ExtEntryTable[j].dispatch_offset;
00508         }
00509         
00510         entry[i] = & ExtEntryTable[j];
00511         break;
00512      }
00513       }
00514    }
00515 
00516    if (offset == ~0) {
00517       offset = next_dynamic_offset;
00518       next_dynamic_offset++;
00519    }
00520 
00521    for ( i = 0 ; function_names[i] != NULL ; i++ ) {
00522       if (! is_static[i] ) {
00523      if (entry[i] == NULL) {
00524         entry[i] = add_function_name( function_names[i] );
00525         if (entry[i] == NULL) {
00526            /* FIXME: Possible memory leak here.
00527         */
00528            return -1;
00529         }
00530      }
00531 
00532      entry[i]->parameter_signature = str_dup(real_sig);
00533      fill_in_entrypoint_offset(entry[i]->dispatch_stub, offset);
00534      entry[i]->dispatch_offset = offset;
00535       }
00536    }
00537    
00538    return offset;
00539 }
00540 
00541 
00545 PUBLIC GLint
00546 _glapi_get_proc_offset(const char *funcName)
00547 {
00548    /* search extension functions first */
00549    GLuint i;
00550    for (i = 0; i < NumExtEntryPoints; i++) {
00551       if (strcmp(ExtEntryTable[i].name, funcName) == 0) {
00552          return ExtEntryTable[i].dispatch_offset;
00553       }
00554    }
00555    /* search static functions */
00556    return get_static_proc_offset(funcName);
00557 }
00558 
00559 
00560 
00566 _glapi_proc
00567 _glapi_get_proc_address(const char *funcName)
00568 {
00569    struct _glapi_function * entry;
00570    GLuint i;
00571 
00572 #ifdef MANGLE
00573    if (funcName[0] != 'm' || funcName[1] != 'g' || funcName[2] != 'l')
00574       return NULL;
00575 #else
00576    if (funcName[0] != 'g' || funcName[1] != 'l')
00577       return NULL;
00578 #endif
00579 
00580    /* search extension functions first */
00581    for (i = 0; i < NumExtEntryPoints; i++) {
00582       if (strcmp(ExtEntryTable[i].name, funcName) == 0) {
00583          return ExtEntryTable[i].dispatch_stub;
00584       }
00585    }
00586 
00587 #if !defined( XFree86Server ) && !defined( XGLServer )
00588    /* search static functions */
00589    {
00590       const _glapi_proc func = get_static_proc_address(funcName);
00591       if (func)
00592          return func;
00593    }
00594 #endif /* !defined( XFree86Server ) */
00595 
00596    entry = add_function_name(funcName);
00597    return (entry == NULL) ? NULL : entry->dispatch_stub;
00598 }
00599 
00600 
00601 
00606 const char *
00607 _glapi_get_proc_name(GLuint offset)
00608 {
00609    GLuint i;
00610    const char * n;
00611 
00612    /* search built-in functions */
00613    n = get_static_proc_name(offset);
00614    if ( n != NULL ) {
00615       return n;
00616    }
00617 
00618    /* search added extension functions */
00619    for (i = 0; i < NumExtEntryPoints; i++) {
00620       if (ExtEntryTable[i].dispatch_offset == offset) {
00621          return ExtEntryTable[i].name;
00622       }
00623    }
00624    return NULL;
00625 }

Generated on Sat May 26 2012 04:18:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.