annotate libmpx/mpxrt/mpxrt.c @ 144:8f4e72ab4e11

fix segmentation fault caused by nothing next cur_op to end
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 21:23:56 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* mpxrt.c -*-C++-*-
kono
parents:
diff changeset
2 *
kono
parents:
diff changeset
3 *************************************************************************
kono
parents:
diff changeset
4 *
kono
parents:
diff changeset
5 * @copyright
kono
parents:
diff changeset
6 * Copyright (C) 2014, Intel Corporation
kono
parents:
diff changeset
7 * All rights reserved.
kono
parents:
diff changeset
8 *
kono
parents:
diff changeset
9 * @copyright
kono
parents:
diff changeset
10 * Redistribution and use in source and binary forms, with or without
kono
parents:
diff changeset
11 * modification, are permitted provided that the following conditions
kono
parents:
diff changeset
12 * are met:
kono
parents:
diff changeset
13 *
kono
parents:
diff changeset
14 * * Redistributions of source code must retain the above copyright
kono
parents:
diff changeset
15 * notice, this list of conditions and the following disclaimer.
kono
parents:
diff changeset
16 * * Redistributions in binary form must reproduce the above copyright
kono
parents:
diff changeset
17 * notice, this list of conditions and the following disclaimer in
kono
parents:
diff changeset
18 * the documentation and/or other materials provided with the
kono
parents:
diff changeset
19 * distribution.
kono
parents:
diff changeset
20 * * Neither the name of Intel Corporation nor the names of its
kono
parents:
diff changeset
21 * contributors may be used to endorse or promote products derived
kono
parents:
diff changeset
22 * from this software without specific prior written permission.
kono
parents:
diff changeset
23 *
kono
parents:
diff changeset
24 * @copyright
kono
parents:
diff changeset
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
kono
parents:
diff changeset
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
kono
parents:
diff changeset
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
kono
parents:
diff changeset
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
kono
parents:
diff changeset
29 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
kono
parents:
diff changeset
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
kono
parents:
diff changeset
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
kono
parents:
diff changeset
32 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
kono
parents:
diff changeset
33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
kono
parents:
diff changeset
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
kono
parents:
diff changeset
35 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
kono
parents:
diff changeset
36 * POSSIBILITY OF SUCH DAMAGE.
kono
parents:
diff changeset
37 *
kono
parents:
diff changeset
38 **************************************************************************/
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 #define __STDC_FORMAT_MACROS
kono
parents:
diff changeset
41 #include "config.h"
kono
parents:
diff changeset
42 #include <inttypes.h>
kono
parents:
diff changeset
43 #include <stdio.h>
kono
parents:
diff changeset
44 #include <string.h>
kono
parents:
diff changeset
45 #include <stdint.h>
kono
parents:
diff changeset
46 #include <stdbool.h>
kono
parents:
diff changeset
47 #include <signal.h>
kono
parents:
diff changeset
48 #include <assert.h>
kono
parents:
diff changeset
49 #include <stdlib.h>
kono
parents:
diff changeset
50 #include <sys/mman.h>
kono
parents:
diff changeset
51 #include <sys/prctl.h>
kono
parents:
diff changeset
52 #include <cpuid.h>
kono
parents:
diff changeset
53 #include "mpxrt-utils.h"
kono
parents:
diff changeset
54 #include "mpxrt.h"
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 #define MPX_ENABLE_BIT_NO 0
kono
parents:
diff changeset
57 #define BNDPRESERVE_BIT_NO 1
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 struct xsave_hdr_struct
kono
parents:
diff changeset
60 {
kono
parents:
diff changeset
61 uint64_t xstate_bv;
kono
parents:
diff changeset
62 uint64_t reserved1[2];
kono
parents:
diff changeset
63 uint64_t reserved2[5];
kono
parents:
diff changeset
64 } __attribute__ ((packed));
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 struct bndregs_struct
kono
parents:
diff changeset
67 {
kono
parents:
diff changeset
68 uint64_t bndregs[8];
kono
parents:
diff changeset
69 } __attribute__ ((packed));
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 struct bndcsr_struct {
kono
parents:
diff changeset
72 uint64_t cfg_reg_u;
kono
parents:
diff changeset
73 uint64_t status_reg;
kono
parents:
diff changeset
74 } __attribute__((packed));
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 struct xsave_struct
kono
parents:
diff changeset
77 {
kono
parents:
diff changeset
78 uint8_t fpu_sse[512];
kono
parents:
diff changeset
79 struct xsave_hdr_struct xsave_hdr;
kono
parents:
diff changeset
80 uint8_t ymm[256];
kono
parents:
diff changeset
81 uint8_t lwp[128];
kono
parents:
diff changeset
82 struct bndregs_struct bndregs;
kono
parents:
diff changeset
83 struct bndcsr_struct bndcsr;
kono
parents:
diff changeset
84 } __attribute__ ((packed));
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 /* Following vars are initialized at process startup only
kono
parents:
diff changeset
87 and thus are considered to be thread safe. */
kono
parents:
diff changeset
88 static void *l1base = NULL;
kono
parents:
diff changeset
89 static int bndpreserve;
kono
parents:
diff changeset
90 static int enable = 1;
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 /* Var holding number of occured BRs. It is modified from
kono
parents:
diff changeset
93 signal handler only and thus it should be thread safe. */
kono
parents:
diff changeset
94 static uint64_t num_bnd_chk = 0;
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 static inline void
kono
parents:
diff changeset
97 xrstor_state (struct xsave_struct *fx, uint64_t mask)
kono
parents:
diff changeset
98 {
kono
parents:
diff changeset
99 uint32_t lmask = mask;
kono
parents:
diff changeset
100 uint32_t hmask = mask >> 32;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
kono
parents:
diff changeset
103 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
kono
parents:
diff changeset
104 : "memory");
kono
parents:
diff changeset
105 }
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 static inline void
kono
parents:
diff changeset
108 xsave_state (struct xsave_struct *fx, uint64_t mask)
kono
parents:
diff changeset
109 {
kono
parents:
diff changeset
110 uint32_t lmask = mask;
kono
parents:
diff changeset
111 uint32_t hmask = mask >> 32;
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
kono
parents:
diff changeset
114 : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask)
kono
parents:
diff changeset
115 : "memory");
kono
parents:
diff changeset
116 }
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 static inline uint64_t
kono
parents:
diff changeset
119 xgetbv (uint32_t index)
kono
parents:
diff changeset
120 {
kono
parents:
diff changeset
121 uint32_t eax, edx;
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 asm volatile (".byte 0x0f,0x01,0xd0" /* xgetbv */
kono
parents:
diff changeset
124 : "=a" (eax), "=d" (edx)
kono
parents:
diff changeset
125 : "c" (index));
kono
parents:
diff changeset
126 return eax + ((uint64_t)edx << 32);
kono
parents:
diff changeset
127 }
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 static uint64_t
kono
parents:
diff changeset
130 read_mpx_status_sig (ucontext_t *uctxt)
kono
parents:
diff changeset
131 {
kono
parents:
diff changeset
132 uint8_t *regs = (uint8_t *)uctxt->uc_mcontext.fpregs + XSAVE_OFFSET_IN_FPMEM;
kono
parents:
diff changeset
133 struct xsave_struct *xsave_buf = (struct xsave_struct *)regs;
kono
parents:
diff changeset
134 return xsave_buf->bndcsr.status_reg;
kono
parents:
diff changeset
135 }
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 static uint8_t *
kono
parents:
diff changeset
138 get_next_inst_ip (uint8_t *addr)
kono
parents:
diff changeset
139 {
kono
parents:
diff changeset
140 uint8_t *ip = addr;
kono
parents:
diff changeset
141 uint8_t sib;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 /* Determine the prefix. */
kono
parents:
diff changeset
144 switch (*ip)
kono
parents:
diff changeset
145 {
kono
parents:
diff changeset
146 case 0xf2:
kono
parents:
diff changeset
147 case 0xf3:
kono
parents:
diff changeset
148 case 0x66:
kono
parents:
diff changeset
149 ip++;
kono
parents:
diff changeset
150 break;
kono
parents:
diff changeset
151 }
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 /* Look for rex prefix. */
kono
parents:
diff changeset
154 if ((*ip & 0x40) == 0x40)
kono
parents:
diff changeset
155 ip++;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 /* Make sure we have a MPX instruction. */
kono
parents:
diff changeset
158 if (*ip++ != 0x0f)
kono
parents:
diff changeset
159 return addr;
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 /* Skip the op code byte. */
kono
parents:
diff changeset
162 ip++;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 /* Get the moderm byte. */
kono
parents:
diff changeset
165 uint8_t modrm = *ip++;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 /* Break it down into parts. */
kono
parents:
diff changeset
168 uint8_t rm = modrm & 7;
kono
parents:
diff changeset
169 uint8_t mod = (modrm >> 6);
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 /* Init the parts of the address mode. */
kono
parents:
diff changeset
172 uint8_t base = 8;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 /* Is it a mem mode? */
kono
parents:
diff changeset
175 if (mod != 3)
kono
parents:
diff changeset
176 {
kono
parents:
diff changeset
177 /* Look for scaled indexed addressing. */
kono
parents:
diff changeset
178 if (rm == 4)
kono
parents:
diff changeset
179 {
kono
parents:
diff changeset
180 /* SIB addressing. */
kono
parents:
diff changeset
181 sib = *ip++;
kono
parents:
diff changeset
182 base = sib & 7;
kono
parents:
diff changeset
183 switch (mod)
kono
parents:
diff changeset
184 {
kono
parents:
diff changeset
185 case 0:
kono
parents:
diff changeset
186 if (base == 5)
kono
parents:
diff changeset
187 ip += 4;
kono
parents:
diff changeset
188 break;
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 case 1:
kono
parents:
diff changeset
191 ip++;
kono
parents:
diff changeset
192 break;
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 case 2:
kono
parents:
diff changeset
195 ip += 4;
kono
parents:
diff changeset
196 break;
kono
parents:
diff changeset
197 }
kono
parents:
diff changeset
198 }
kono
parents:
diff changeset
199 else
kono
parents:
diff changeset
200 {
kono
parents:
diff changeset
201 /* MODRM addressing. */
kono
parents:
diff changeset
202 switch (mod)
kono
parents:
diff changeset
203 {
kono
parents:
diff changeset
204 case 0:
kono
parents:
diff changeset
205 if (rm == 5)
kono
parents:
diff changeset
206 /* DISP32 addressing, no base. */
kono
parents:
diff changeset
207 ip += 4;
kono
parents:
diff changeset
208 break;
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 case 1:
kono
parents:
diff changeset
211 ip++;
kono
parents:
diff changeset
212 break;
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 case 2:
kono
parents:
diff changeset
215 ip += 4;
kono
parents:
diff changeset
216 break;
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218 }
kono
parents:
diff changeset
219 }
kono
parents:
diff changeset
220 return ip;
kono
parents:
diff changeset
221 }
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 static void
kono
parents:
diff changeset
224 handler (int sig __attribute__ ((unused)),
kono
parents:
diff changeset
225 siginfo_t *info __attribute__ ((unused)),
kono
parents:
diff changeset
226 void *vucontext,
kono
parents:
diff changeset
227 struct xsave_struct *buf __attribute__ ((unused)))
kono
parents:
diff changeset
228 {
kono
parents:
diff changeset
229 ucontext_t* uctxt;
kono
parents:
diff changeset
230 greg_t trapno;
kono
parents:
diff changeset
231 greg_t ip;
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 uctxt = vucontext;
kono
parents:
diff changeset
234 trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO];
kono
parents:
diff changeset
235 ip = uctxt->uc_mcontext.gregs[REG_IP_IDX];
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 if (trapno == 5)
kono
parents:
diff changeset
238 {
kono
parents:
diff changeset
239 uint64_t status = read_mpx_status_sig (uctxt);
kono
parents:
diff changeset
240 uint64_t br_reason = status & 0x3;
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 __mpxrt_write (VERB_BR, "Saw a #BR! status ");
kono
parents:
diff changeset
243 __mpxrt_write_uint (VERB_BR, status, 10);
kono
parents:
diff changeset
244 __mpxrt_write (VERB_BR, " at 0x");
kono
parents:
diff changeset
245 __mpxrt_write_uint (VERB_BR, ip, 16);
kono
parents:
diff changeset
246 __mpxrt_write (VERB_BR, "\n");
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 switch (br_reason)
kono
parents:
diff changeset
249 {
kono
parents:
diff changeset
250 case 1: /* traditional BR */
kono
parents:
diff changeset
251 num_bnd_chk++;
kono
parents:
diff changeset
252 uctxt->uc_mcontext.gregs[REG_IP_IDX] =
kono
parents:
diff changeset
253 (greg_t)get_next_inst_ip ((uint8_t *)ip);
kono
parents:
diff changeset
254 if (__mpxrt_mode () == MPX_RT_STOP)
kono
parents:
diff changeset
255 __mpxrt_stop ();
kono
parents:
diff changeset
256 return;
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 default:
kono
parents:
diff changeset
259 __mpxrt_write (VERB_BR, "Unexpected status with bound exception: ");
kono
parents:
diff changeset
260 __mpxrt_write_uint (VERB_BR, status, 10);
kono
parents:
diff changeset
261 __mpxrt_write (VERB_BR, "\n");
kono
parents:
diff changeset
262 break;
kono
parents:
diff changeset
263 }
kono
parents:
diff changeset
264 }
kono
parents:
diff changeset
265 else if (trapno == 14)
kono
parents:
diff changeset
266 {
kono
parents:
diff changeset
267 __mpxrt_write (VERB_ERROR, "In signal handler, trapno = ");
kono
parents:
diff changeset
268 __mpxrt_write_uint (VERB_ERROR, trapno, 10);
kono
parents:
diff changeset
269 __mpxrt_write (VERB_ERROR, ", ip = 0x");
kono
parents:
diff changeset
270 __mpxrt_write_uint (VERB_ERROR, ip, 16);
kono
parents:
diff changeset
271 __mpxrt_write (VERB_ERROR, "\n");
kono
parents:
diff changeset
272 __mpxrt_stop ();
kono
parents:
diff changeset
273 }
kono
parents:
diff changeset
274 else
kono
parents:
diff changeset
275 {
kono
parents:
diff changeset
276 __mpxrt_write (VERB_ERROR, "Unexpected trap ");
kono
parents:
diff changeset
277 __mpxrt_write_uint (VERB_ERROR, trapno, 10);
kono
parents:
diff changeset
278 __mpxrt_write (VERB_ERROR, "! at 0x");
kono
parents:
diff changeset
279 __mpxrt_write_uint (VERB_ERROR, ip, 16);
kono
parents:
diff changeset
280 __mpxrt_write (VERB_ERROR, "\n");
kono
parents:
diff changeset
281 __mpxrt_stop ();
kono
parents:
diff changeset
282 }
kono
parents:
diff changeset
283 }
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 /* Using wrapper to the real handler in order to save the bnd regs
kono
parents:
diff changeset
286 using xsave before any unprefixed call. an unprefixed call to
kono
parents:
diff changeset
287 __i686.get_pc_thunk.bx is added by the linker in 32bit at the
kono
parents:
diff changeset
288 beginning of handler function since there are references to
kono
parents:
diff changeset
289 global variables. */
kono
parents:
diff changeset
290 static void
kono
parents:
diff changeset
291 handler_wrap (int signum, siginfo_t* si, void* vucontext)
kono
parents:
diff changeset
292 {
kono
parents:
diff changeset
293 /* Since the OS currently not handling chkptr regs.
kono
parents:
diff changeset
294 We need to store them for later use. They might be
kono
parents:
diff changeset
295 init due to unprefixed call,Jcc,ret. avoiding calling
kono
parents:
diff changeset
296 function since the function will be unprefixed as well. */
kono
parents:
diff changeset
297 uint8_t __attribute__ ((__aligned__ (64))) buffer[4096];
kono
parents:
diff changeset
298 struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer;
kono
parents:
diff changeset
299 uint64_t mask = 0x18;
kono
parents:
diff changeset
300 uint32_t lmask = mask;
kono
parents:
diff changeset
301 uint32_t hmask = mask >> 32;
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x27\n\t"
kono
parents:
diff changeset
304 : : "D" (xsave_buf), "m" (*xsave_buf),
kono
parents:
diff changeset
305 "a" (lmask), "d" (hmask)
kono
parents:
diff changeset
306 : "memory");
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308 handler (signum, si, vucontext, xsave_buf);
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 static bool
kono
parents:
diff changeset
312 check_mpx_support (void)
kono
parents:
diff changeset
313 {
kono
parents:
diff changeset
314 unsigned int eax, ebx, ecx, edx;
kono
parents:
diff changeset
315 unsigned int max_level = __get_cpuid_max (0, NULL);
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 if (max_level < 13)
kono
parents:
diff changeset
318 {
kono
parents:
diff changeset
319 __mpxrt_print (VERB_DEBUG, "No required CPUID level support.\n");
kono
parents:
diff changeset
320 return false;
kono
parents:
diff changeset
321 }
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 __cpuid_count (0, 0, eax, ebx, ecx, edx);
kono
parents:
diff changeset
324 if (!(ecx & bit_XSAVE))
kono
parents:
diff changeset
325 {
kono
parents:
diff changeset
326 __mpxrt_print (VERB_DEBUG, "No XSAVE support.\n");
kono
parents:
diff changeset
327 return false;
kono
parents:
diff changeset
328 }
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 if (!(ecx & bit_OSXSAVE))
kono
parents:
diff changeset
331 {
kono
parents:
diff changeset
332 __mpxrt_print (VERB_DEBUG, "No OSXSAVE support.\n");
kono
parents:
diff changeset
333 return false;
kono
parents:
diff changeset
334 }
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 __cpuid_count (7, 0, eax, ebx, ecx, edx);
kono
parents:
diff changeset
337 if (!(ebx & bit_MPX))
kono
parents:
diff changeset
338 {
kono
parents:
diff changeset
339 __mpxrt_print (VERB_DEBUG, "No MPX support.\n");
kono
parents:
diff changeset
340 return false;
kono
parents:
diff changeset
341 }
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 __cpuid_count (13, 0, eax, ebx, ecx, edx);
kono
parents:
diff changeset
344 if (!(eax & bit_BNDREGS))
kono
parents:
diff changeset
345 {
kono
parents:
diff changeset
346 __mpxrt_print (VERB_DEBUG, "No BNDREGS support.\n");
kono
parents:
diff changeset
347 return false;
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 if (!(eax & bit_BNDCSR))
kono
parents:
diff changeset
351 {
kono
parents:
diff changeset
352 __mpxrt_print (VERB_DEBUG, "No BNDCSR support.\n");
kono
parents:
diff changeset
353 return false;
kono
parents:
diff changeset
354 }
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 return true;
kono
parents:
diff changeset
357 }
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 static void
kono
parents:
diff changeset
360 enable_mpx (void)
kono
parents:
diff changeset
361 {
kono
parents:
diff changeset
362 uint8_t __attribute__ ((__aligned__ (64))) buffer[4096];
kono
parents:
diff changeset
363 struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 memset (buffer, 0, sizeof (buffer));
kono
parents:
diff changeset
366 xrstor_state (xsave_buf, 0x18);
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 __mpxrt_print (VERB_DEBUG, "Initalizing MPX...\n");
kono
parents:
diff changeset
369 __mpxrt_print (VERB_DEBUG, " Enable bit: %d\n", enable);
kono
parents:
diff changeset
370 __mpxrt_print (VERB_DEBUG, " BNDPRESERVE bit: %d\n", bndpreserve);
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 /* Enable MPX. */
kono
parents:
diff changeset
373 xsave_buf->xsave_hdr.xstate_bv = 0x10;
kono
parents:
diff changeset
374 xsave_buf->bndcsr.cfg_reg_u = (unsigned long)l1base;
kono
parents:
diff changeset
375 xsave_buf->bndcsr.cfg_reg_u |= enable << MPX_ENABLE_BIT_NO;
kono
parents:
diff changeset
376 xsave_buf->bndcsr.cfg_reg_u |= bndpreserve << BNDPRESERVE_BIT_NO;
kono
parents:
diff changeset
377 xsave_buf->bndcsr.status_reg = 0;
kono
parents:
diff changeset
378
kono
parents:
diff changeset
379 xrstor_state (xsave_buf, 0x10);
kono
parents:
diff changeset
380 }
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 static void
kono
parents:
diff changeset
383 disable_mpx (void)
kono
parents:
diff changeset
384 {
kono
parents:
diff changeset
385 uint8_t __attribute__ ((__aligned__ (64))) buffer[4096];
kono
parents:
diff changeset
386 struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer;
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 memset(buffer, 0, sizeof(buffer));
kono
parents:
diff changeset
389 xrstor_state(xsave_buf, 0x18);
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 /* Disable MPX. */
kono
parents:
diff changeset
392 xsave_buf->xsave_hdr.xstate_bv = 0x10;
kono
parents:
diff changeset
393 xsave_buf->bndcsr.cfg_reg_u = 0;
kono
parents:
diff changeset
394 xsave_buf->bndcsr.status_reg = 0;
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 xrstor_state(xsave_buf, 0x10);
kono
parents:
diff changeset
397 }
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399 static bool
kono
parents:
diff changeset
400 process_specific_init (void)
kono
parents:
diff changeset
401 {
kono
parents:
diff changeset
402 if (!check_mpx_support ())
kono
parents:
diff changeset
403 return false;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 l1base = mmap (NULL, MPX_L1_SIZE, PROT_READ | PROT_WRITE,
kono
parents:
diff changeset
406 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
kono
parents:
diff changeset
407 if (l1base == MAP_FAILED)
kono
parents:
diff changeset
408 {
kono
parents:
diff changeset
409 perror ("mmap");
kono
parents:
diff changeset
410 exit (EXIT_FAILURE);
kono
parents:
diff changeset
411 }
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 enable_mpx ();
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 if (prctl (43, 0, 0, 0, 0))
kono
parents:
diff changeset
416 {
kono
parents:
diff changeset
417 __mpxrt_print (VERB_ERROR, "No MPX support\n");
kono
parents:
diff changeset
418 disable_mpx ();
kono
parents:
diff changeset
419 return false;
kono
parents:
diff changeset
420 }
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 return true;
kono
parents:
diff changeset
423 }
kono
parents:
diff changeset
424
kono
parents:
diff changeset
425 static bool
kono
parents:
diff changeset
426 process_specific_finish (void)
kono
parents:
diff changeset
427 {
kono
parents:
diff changeset
428 if (!check_mpx_support ())
kono
parents:
diff changeset
429 return false;
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 if (prctl (44, 0, 0, 0, 0))
kono
parents:
diff changeset
432 {
kono
parents:
diff changeset
433 __mpxrt_print (VERB_ERROR, "No MPX support\n");
kono
parents:
diff changeset
434 return false;
kono
parents:
diff changeset
435 }
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 munmap (l1base, MPX_L1_SIZE);
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 return true;
kono
parents:
diff changeset
440 }
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 static void
kono
parents:
diff changeset
443 setup_handler (void)
kono
parents:
diff changeset
444 {
kono
parents:
diff changeset
445 int r,rs;
kono
parents:
diff changeset
446 struct sigaction newact;
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 /* #BR is mapped to sigsegv */
kono
parents:
diff changeset
449 int signum = SIGSEGV;
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 newact.sa_handler = 0;
kono
parents:
diff changeset
452 newact.sa_sigaction = handler_wrap;
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 /* sigset_t - signals to block while in the handler
kono
parents:
diff changeset
455 get the old signal mask. */
kono
parents:
diff changeset
456 rs = sigprocmask (SIG_SETMASK, 0, &newact.sa_mask);
kono
parents:
diff changeset
457 assert (rs == 0);
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 /* Call sa_sigaction, not sa_handler. */
kono
parents:
diff changeset
460 newact.sa_flags = SA_SIGINFO;
kono
parents:
diff changeset
461 /* In case we call user's handler on SIGSEGV (not bound
kono
parents:
diff changeset
462 violation exception) we want to allow bound checking
kono
parents:
diff changeset
463 inside the user handler -> nested exception. */
kono
parents:
diff changeset
464 newact.sa_flags |= SA_NODEFER;
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 newact.sa_restorer = 0;
kono
parents:
diff changeset
467 r = sigaction (signum, &newact, 0);
kono
parents:
diff changeset
468 assert (r == 0);
kono
parents:
diff changeset
469 }
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 /* Set constructor priority to two to make it run after the
kono
parents:
diff changeset
472 constructor in sigaction.c. */
kono
parents:
diff changeset
473 static void __attribute__ ((constructor (1005)))
kono
parents:
diff changeset
474 mpxrt_prepare (void)
kono
parents:
diff changeset
475 {
kono
parents:
diff changeset
476 __mpxrt_init_env_vars (&bndpreserve);
kono
parents:
diff changeset
477 setup_handler ();
kono
parents:
diff changeset
478 process_specific_init ();
kono
parents:
diff changeset
479 }
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 static void __attribute__ ((destructor))
kono
parents:
diff changeset
482 mpxrt_cleanup (void)
kono
parents:
diff changeset
483 {
kono
parents:
diff changeset
484 __mpxrt_print_summary (num_bnd_chk, MPX_L1_SIZE);
kono
parents:
diff changeset
485 __mpxrt_utils_free ();
kono
parents:
diff changeset
486 process_specific_finish ();
kono
parents:
diff changeset
487 }
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 /* Get address of bounds directory. */
kono
parents:
diff changeset
490 void *
kono
parents:
diff changeset
491 get_bd ()
kono
parents:
diff changeset
492 {
kono
parents:
diff changeset
493 return l1base;
kono
parents:
diff changeset
494 }