Home | History | Annotate | Download | only in mapi
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 
     26 /**
     27  * \file glapi_execmem.c
     28  *
     29  * Function for allocating executable memory for dispatch stubs.
     30  *
     31  * Copied from main/execmem.c and simplified for dispatch stubs.
     32  */
     33 
     34 
     35 #include "c99_compat.h"
     36 #include "c11/threads.h"
     37 #include "u_execmem.h"
     38 
     39 
     40 #define EXEC_MAP_SIZE (4*1024)
     41 
     42 static mtx_t exec_mutex = _MTX_INITIALIZER_NP;
     43 
     44 static unsigned int head = 0;
     45 
     46 static unsigned char *exec_mem = (unsigned char *)0;
     47 
     48 
     49 #if defined(__linux__) || defined(__OpenBSD__) || defined(_NetBSD__) || defined(__sun) || defined(__HAIKU__)
     50 
     51 #include <unistd.h>
     52 #include <sys/mman.h>
     53 
     54 #ifdef MESA_SELINUX
     55 #include <selinux/selinux.h>
     56 #endif
     57 
     58 
     59 #ifndef MAP_ANONYMOUS
     60 #define MAP_ANONYMOUS MAP_ANON
     61 #endif
     62 
     63 
     64 /*
     65  * Dispatch stubs are of fixed size and never freed. Thus, we do not need to
     66  * overlay a heap, we just mmap a page and manage through an index.
     67  */
     68 
     69 static int
     70 init_map(void)
     71 {
     72 #ifdef MESA_SELINUX
     73    if (is_selinux_enabled()) {
     74       if (!security_get_boolean_active("allow_execmem") ||
     75 	  !security_get_boolean_pending("allow_execmem"))
     76          return 0;
     77    }
     78 #endif
     79 
     80    if (!exec_mem)
     81       exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
     82 		      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     83 
     84    return (exec_mem != MAP_FAILED);
     85 }
     86 
     87 
     88 #elif defined(_WIN32)
     89 
     90 #include <windows.h>
     91 
     92 
     93 /*
     94  * Avoid Data Execution Prevention.
     95  */
     96 
     97 static int
     98 init_map(void)
     99 {
    100    exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    101 
    102    return (exec_mem != NULL);
    103 }
    104 
    105 
    106 #else
    107 
    108 #include <stdlib.h>
    109 
    110 static int
    111 init_map(void)
    112 {
    113    exec_mem = malloc(EXEC_MAP_SIZE);
    114 
    115    return (exec_mem != NULL);
    116 }
    117 
    118 
    119 #endif
    120 
    121 void *
    122 u_execmem_alloc(unsigned int size)
    123 {
    124    void *addr = NULL;
    125 
    126    mtx_lock(&exec_mutex);
    127 
    128    if (!init_map())
    129       goto bail;
    130 
    131    /* free space check, assumes no integer overflow */
    132    if (head + size > EXEC_MAP_SIZE)
    133       goto bail;
    134 
    135    /* allocation, assumes proper addr and size alignement */
    136    addr = exec_mem + head;
    137    head += size;
    138 
    139 bail:
    140    mtx_unlock(&exec_mutex);
    141 
    142    return addr;
    143 }
    144 
    145 
    146