~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/mapi/u_execmem.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "c11/threads.h"
36
 
#include "util/u_call_once.h"
37
 
#include "u_execmem.h"
38
 
 
39
 
 
40
 
#define EXEC_MAP_SIZE (4*1024)
41
 
 
42
 
static mtx_t exec_mutex;
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
 
   exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
81
 
                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
82
 
 
83
 
   return (exec_mem != MAP_FAILED);
84
 
}
85
 
 
86
 
 
87
 
#elif defined(_WIN32)
88
 
 
89
 
#include <windows.h>
90
 
 
91
 
 
92
 
/*
93
 
 * Avoid Data Execution Prevention.
94
 
 */
95
 
 
96
 
static int
97
 
init_map(void)
98
 
{
99
 
   exec_mem = VirtualAlloc(NULL, EXEC_MAP_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
100
 
 
101
 
   return (exec_mem != NULL);
102
 
}
103
 
 
104
 
 
105
 
#else
106
 
 
107
 
#include <stdlib.h>
108
 
 
109
 
static int
110
 
init_map(void)
111
 
{
112
 
   exec_mem = malloc(EXEC_MAP_SIZE);
113
 
 
114
 
   return (exec_mem != NULL);
115
 
}
116
 
 
117
 
 
118
 
#endif
119
 
 
120
 
static void
121
 
u_execmem_init_once(void)
122
 
{
123
 
   if (!init_map())
124
 
      exec_mem = NULL;
125
 
   mtx_init(&exec_mutex, mtx_plain);
126
 
}
127
 
 
128
 
void *
129
 
u_execmem_alloc(unsigned int size)
130
 
{
131
 
#ifndef MESA_EXECMEM
132
 
   (void)size;
133
 
   return NULL;
134
 
#else
135
 
   void *addr = NULL;
136
 
   static util_once_flag once = UTIL_ONCE_FLAG_INIT;
137
 
   util_call_once(&once, u_execmem_init_once);
138
 
   if (exec_mem == NULL)
139
 
      return NULL;
140
 
 
141
 
   mtx_lock(&exec_mutex);
142
 
 
143
 
   /* free space check, assumes no integer overflow */
144
 
   if (head + size > EXEC_MAP_SIZE)
145
 
      goto bail;
146
 
 
147
 
   /* allocation, assumes proper addr and size alignement */
148
 
   addr = exec_mem + head;
149
 
   head += size;
150
 
 
151
 
bail:
152
 
   mtx_unlock(&exec_mutex);
153
 
 
154
 
   return addr;
155
 
#endif /* MESA_EXECMEM */
156
 
}
157
 
 
158