1 /* Page fault handling library.
2 Copyright (C) 1993-2023 Free Software Foundation, Inc.
3 Copyright (C) 2018 Nylon Chen <nylon7@andestech.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18 /* Written by Bruno Haible and Nylon Chen. */
19
20 #include <config.h>
21
22 /* Specification. */
23 #include "sigsegv.h"
24
25 #include <errno.h>
26 #include <stdio.h> /* declares perror */
27 #include <stdint.h> /* defines uintptr_t */
28 #include <stdlib.h>
29 #include <signal.h>
30 #if HAVE_GETRLIMIT
31 # include <sys/resource.h> /* declares struct rlimit */
32 #endif
33
34 #ifdef __OpenBSD__
35 # include <sys/param.h> /* defines macro OpenBSD */
36 #endif
37
38
39 /* Version number. */
40 int libsigsegv_version = LIBSIGSEGV_VERSION;
41
42
43 /* ======================= Fault handler information ======================= */
44
45 /* Define:
46
47 SIGSEGV_FAULT_HANDLER_ARGLIST
48 is the argument list for the actual fault handler.
49
50 and if available (optional):
51
52 SIGSEGV_FAULT_ADDRESS
53 is a macro for fetching the fault address.
54
55 SIGSEGV_FAULT_CONTEXT
56 is a macro giving a pointer to the entire fault context (i.e.
57 the register set etc.).
58
59 SIGSEGV_FAULT_STACKPOINTER
60 is a macro for fetching the stackpointer at the moment the fault
61 occurred.
62 */
63
64 #if defined __linux__ && !defined __ANDROID__ /* Linux */
65
66 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
67 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
68 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
69 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
70
71 # if defined __alpha__
72
73 /* See glibc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
74 and the definition of GET_STACK in
75 glibc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h.
76 Note that the 'mcontext_t' defined in
77 glibc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
78 and the 'struct sigcontext' defined in <asm/sigcontext.h>
79 are actually the same. */
80
81 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_regs[30]
82
83 # elif defined __arm64__ /* 64-bit */
84
85 /* See glibc/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h.
86 Note that the 'mcontext_t' defined in
87 glibc/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
88 and the 'struct sigcontext' defined in <asm/sigcontext.h>
89 are actually the same. */
90
91 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sp
92
93 # elif defined __arm__ || defined __armhf__ /* 32-bit */
94
95 /* See glibc/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
96 and the definition of GET_STACK in
97 glibc/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h.
98 Note that the 'mcontext_t' defined in
99 glibc/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
100 and the 'struct sigcontext' defined in <asm/sigcontext.h>
101 are actually the same. */
102
103 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.arm_sp
104
105 # elif defined __cris__
106
107 /* See glibc-ports/sysdeps/unix/sysv/linux/cris/sys/ucontext.h.
108 Note that the 'mcontext_t' defined in
109 glibc-ports/sysdeps/unix/sysv/linux/cris/sys/ucontext.h
110 and the 'struct sigcontext' defined in <asm/sigcontext.h>
111 are actually the same. */
112
113 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.usp
114
115 # elif defined __hppa__
116
117 /* See glibc/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h.
118 Note that the 'mcontext_t' defined in
119 glibc/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h
120 and the 'struct sigcontext' defined in <asm/sigcontext.h>
121 are actually the same. */
122
123 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_gr[30]
124
125 # elif defined __x86_64__ /* 64 bit registers */
126
127 /* See glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
128 and the definition of GET_STACK in
129 glibc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h.
130 Note that the 'mcontext_t' defined in
131 glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
132 and the 'struct sigcontext' defined in
133 glibc/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h
134 (see also <asm/sigcontext.h>)
135 are effectively the same. */
136
137 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_RSP]
138
139 # elif defined __i386__ /* 32 bit registers */
140
141 /* See glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
142 and the definition of GET_STACK in
143 glibc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h.
144 Note that the 'mcontext_t' defined in
145 glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
146 and the 'struct sigcontext_ia32' defined in <asm/sigcontext32.h>
147 are effectively the same. */
148
149 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_ESP]
150 /* same value as ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_UESP] */
151
152 # elif defined __ia64__
153
154 /* See glibc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h.
155 Note that the 'mcontext_t' defined in
156 glibc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h
157 and the 'struct sigcontext' defined in
158 glibc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
159 (see also <asm/sigcontext.h>)
160 are actually the same. */
161
162 /* IA-64 has two stack pointers, one that grows down, called $r12, and one
163 that grows up, called $bsp/$bspstore. */
164 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_gr[12]
165
166 /* It would be better to access $bspstore instead of $bsp but I don't know
167 where to find it in 'struct sigcontext'. Anyway, it doesn't matter
168 because $bsp and $bspstore never differ by more than ca. 1 KB. */
169 # define SIGSEGV_FAULT_BSP_POINTER ((ucontext_t *) ucp)->uc_mcontext.sc_ar_bsp
170
171 # elif defined __loongarch__
172
173 /* See <sys/ucontext.h>.
174 Note that the 'mcontext_t' defined in <sys/ucontext.h>
175 and the 'struct sigcontext' defined in <bits/sigcontext.h>
176 (see also <asm/sigcontext.h>) are effectively the same. */
177
178 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[3]
179
180 # elif defined __m68k__
181
182 /* See glibc/sysdeps/unix/sysv/linux/m68k/sys/ucontext.h
183 and the definition of GET_STACK in
184 glibc/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h.
185 Note that the 'mcontext_t' defined in
186 glibc/sysdeps/unix/sysv/linux/m68k/sys/ucontext.h
187 and the 'struct sigcontext' defined in <asm/sigcontext.h>
188 are quite different types. */
189
190 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[R_SP]
191
192 # elif defined __mips__ || defined __mipsn32__ || defined __mips64__
193
194 /* See glibc/sysdeps/unix/sysv/linux/mips/sys/ucontext.h
195 and the definition of GET_STACK in
196 glibc/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h.
197 Note that the 'mcontext_t' defined in
198 glibc/sysdeps/unix/sysv/linux/mips/sys/ucontext.h
199 and the 'struct sigcontext' defined in
200 glibc/sysdeps/unix/sysv/linux/mips/bits/sigcontext.h
201 (see also <asm/sigcontext.h>)
202 are effectively the same. */
203
204 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[29]
205
206 # elif defined __nds32__
207
208 /* See glibc/sysdeps/unix/sysv/linux/nds32/sys/ucontext.h
209 and the definition of GET_STACK in
210 glibc/sysdeps/unix/sysv/linux/nds32/sigcontextinfo.h.
211 Both are found in <https://patches-gcc.linaro.org/cover/4409/> part 08/11
212 <https://sourceware.org/ml/libc-alpha/2018-05/msg00125.html>. */
213
214 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.nds32_sp
215
216 # elif defined __powerpc__ || defined __powerpc64__ || defined __powerpc64_elfv2__
217
218 /* See glibc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h
219 and the definition of GET_STACK in
220 glibc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h.
221 Note that the 'mcontext_t' defined in
222 glibc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h,
223 the 'struct sigcontext' defined in <asm/sigcontext.h>,
224 and the 'struct pt_regs' defined in <asm/ptrace.h>
225 are quite different types. */
226
227 # if defined __powerpc64__ || defined __powerpc64_elfv2__ /* 64-bit */
228 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gp_regs[1]
229 # else /* 32-bit */
230 # if MUSL_LIBC
231 /* musl libc has a different structure of ucontext_t in
232 musl/arch/powerpc/bits/signal.h. */
233 /* The glibc comments say:
234 "Different versions of the kernel have stored the registers on signal
235 delivery at different offsets from the ucontext struct. Programs should
236 thus use the uc_mcontext.uc_regs pointer to find where the registers are
237 actually stored." */
238 # if 0
239 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[1]
240 # else
241 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_regs->gregs[1]
242 # endif
243 # else
244 /* Assume the structure of ucontext_t in
245 glibc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h. */
246 /* Because of the union, both definitions should be equivalent. */
247 # if 0
248 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.regs->gpr[1]
249 # else
250 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.uc_regs->gregs[1]
251 # endif
252 # endif
253 # endif
254
255 # elif defined __riscv32__ || __riscv64__
256
257 /* See glibc/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
258 and the definition of GET_STACK in
259 glibc/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h.
260 Note that the 'mcontext_t' defined in
261 glibc/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
262 and the 'struct sigcontext' defined in
263 glibc/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
264 start with the same block of 32 general-purpose registers. */
265
266 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[REG_SP]
267
268 # elif defined __s390__ || defined __s390x__
269
270 /* See glibc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
271 and the definition of GET_STACK in
272 glibc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h.
273 Note that the 'mcontext_t' defined in
274 glibc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
275 and the '_sigregs' type, indirect part of 'struct sigcontext', defined
276 in <asm/sigcontext.h>, are effectively the same. */
277
278 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[15]
279
280 # elif defined __sh__
281
282 /* See glibc/sysdeps/unix/sysv/linux/sh/sys/ucontext.h
283 and the definition of GET_STACK in
284 glibc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h.
285 Note that the 'mcontext_t' defined in
286 glibc/sysdeps/unix/sysv/linux/sh/sys/ucontext.h
287 and the 'struct sigcontext' defined in <asm/sigcontext.h>
288 are effectively the same. */
289
290 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[15]
291
292 # elif defined __sparc__ || defined __sparc64__
293
294 /* See glibc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
295 and the definition of GET_STACK in
296 glibc/sysdeps/unix/sysv/linux/sparc/{sparc32,sparc64}/sigcontextinfo.h.
297 Note that the 'mcontext_t' defined in
298 glibc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
299 and the 'struct sigcontext' defined in
300 glibc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h
301 (see also <asm/sigcontext.h>)
302 are quite different types. */
303
304 # if defined __sparc64__/* 64-bit */
305 /* From linux-4.8.1/arch/sparc/kernel/signal_64.c, function setup_rt_frame, we
306 see that ucp is not an 'ucontext_t *' but rather a 'struct sigcontext *'
307 that happens to have the same value as sip (which is possible because a
308 'struct sigcontext' starts with 128 bytes room for the siginfo_t). */
309 # define SIGSEGV_FAULT_STACKPOINTER (((struct sigcontext *) ucp)->sigc_regs.u_regs[14] + 2047)
310 # else /* 32-bit */
311 /* From linux-4.8.1/arch/sparc/kernel/signal_32.c, function setup_rt_frame,
312 and linux-4.8.1/arch/sparc/kernel/signal32.c, function setup_rt_frame32, we
313 see that ucp is a 'struct pt_regs *' or 'struct pt_regs32 *', respectively.
314 In userland, this is a 'struct sigcontext *'. */
315 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) ucp)->si_regs.u_regs[14]
316 # endif
317
318 /* The sip->si_addr field is correct for a normal fault, but unusable in case
319 of a stack overflow. What I observe (when running
320 tests/test-sigsegv-catch-stackoverflow1, with a printf right at the beginning
321 of sigsegv_handler) is that sip->si_addr is near 0:
322 - in 64-bit mode: sip->si_addr = 0x000000000000030F, and gdb shows me that
323 the fault occurs in an instruction 'stx %o3,[%fp+0x30f]' and %fp is 0.
324 In fact, all registers %l0..%l7 and %i0..%i7 are 0.
325 - in 32-bit mode: sip->si_addr = 0xFFFFFA64, and gdb shows me that
326 the fault occurs in an instruction 'st %g2,[%fp-1436]' and %fp is 0.
327 In fact, all registers %l0..%l7 and %i0..%i7 are 0.
328 Apparently when the stack overflow occurred, some trap has tried to move the
329 contents of the registers %l0..%l7 and %i0..%i7 (a "window" in SPARC
330 terminology) to the stack, did not succeed in doing this, replaced all these
331 register values with 0, and resumed execution at the fault location. This
332 time, due to %fp = 0, a different fault was triggered. Now it is impossible
333 to determine the real (previous) fault address because, even if know the
334 faulting instruction, the previous register values have been lost. */
335 # define BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
336
337 # else
338
339 /* When adding support for other CPUs here: */
340
341 /* For SIGSEGV_FAULT_HANDLER_ARGLIST, see the definition of SIGCONTEXT in
342 glibc/sysdeps/unix/sysv/linux/<cpu>/sigcontextinfo.h. */
343
344 /* For SIGSEGV_FAULT_STACKPOINTER, see the definition of GET_STACK in
345 glibc/sysdeps/unix/sysv/linux/<cpu>/sigcontextinfo.h. */
346
347 # endif
348
349 #endif
350
351 #if defined __ANDROID__ /* Android */
352 /* A platform that supports the POSIX:2008 (XPG 7) way, without
353 'struct sigcontext' nor 'ucontext_t'. */
354
355 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *context
356 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
357 # define SIGSEGV_FAULT_CONTEXT context
358 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
359
360 #endif
361
362 #if defined __GNU__ /* Hurd */
363
364 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, long code, struct sigcontext *scp
365 # define SIGSEGV_FAULT_ADDRESS (unsigned long) code
366 # define SIGSEGV_FAULT_CONTEXT scp
367
368 # if defined __x86_64__
369 /* 64 bit registers */
370
371 /* scp points to a 'struct sigcontext' (defined in
372 glibc/sysdeps/mach/hurd/x86_64/bits/sigcontext.h).
373 The registers, at the moment the signal occurred, get pushed on the kernel
374 stack through gnumach/x86_64/locore.S:alltraps. They are denoted by a
375 'struct i386_saved_state' (defined in gnumach/i386/i386/thread.h).
376 Upon invocation of the Mach interface function thread_get_state
377 <https://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html>
378 (= __thread_get_state in glibc), defined in gnumach/kern/thread.c,
379 the function thread_getstatus, defined in gnumach/i386/i386/pcb.c, copies the
380 register values in a different arrangement into a 'struct i386_thread_state',
381 defined in gnumach/i386/include/mach/i386/thread_status.h. (Different
382 arrangement: trapno, err get dropped; different order of r8...r15; also rsp
383 gets set to 0.)
384 This 'struct i386_thread_state' is actually the 'basic' part of a
385 'struct machine_thread_all_state', defined in
386 glibc/sysdeps/mach/x86/thread_state.h.
387 From there, the function _hurd_setup_sighandler, defined in
388 glibc/sysdeps/mach/hurd/x86/trampoline.c,
389 1. sets rsp to the same value as ursp,
390 2. copies the 'struct i386_thread_state' into the appropriate part of a
391 'struct sigcontext', defined in
392 glibc/sysdeps/mach/hurd/x86_64/bits/sigcontext.h. */
393 /* Both sc_rsp and sc_ursp have the same value.
394 It appears more reliable to use sc_ursp because sc_rsp is marked as
395 "not used". */
396 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_ursp
397
398 # elif defined __i386__
399 /* 32 bit registers */
400
401 /* scp points to a 'struct sigcontext' (defined in
402 glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h).
403 The registers, at the moment the signal occurred, get pushed on the kernel
404 stack through gnumach/i386/i386/locore.S:alltraps. They are denoted by a
405 'struct i386_saved_state' (defined in gnumach/i386/i386/thread.h).
406 Upon invocation of the Mach interface function thread_get_state
407 <https://www.gnu.org/software/hurd/gnumach-doc/Thread-Execution.html>
408 (= __thread_get_state in glibc), defined in gnumach/kern/thread.c,
409 the function thread_getstatus, defined in gnumach/i386/i386/pcb.c, copies the
410 register values in a different arrangement into a 'struct i386_thread_state',
411 defined in gnumach/i386/include/mach/i386/thread_status.h. (Different
412 arrangement: trapno, err get dropped; also esp gets set to 0.)
413 This 'struct i386_thread_state' is actually the 'basic' part of a
414 'struct machine_thread_all_state', defined in
415 glibc/sysdeps/mach/x86/thread_state.h.
416 From there, the function _hurd_setup_sighandler, defined in
417 glibc/sysdeps/mach/hurd/x86/trampoline.c,
418 1. sets esp to the same value as uesp,
419 2. copies the 'struct i386_thread_state' into the appropriate part of a
420 'struct sigcontext', defined in
421 glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h. */
422 /* Both sc_esp and sc_uesp have the same value.
423 It appears more reliable to use sc_uesp because sc_esp is marked as
424 "not used". */
425 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_uesp
426
427 # endif
428
429 #endif
430
431 #if defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ /* GNU/kFreeBSD, FreeBSD */
432
433 # if defined __arm__ || defined __armhf__ || defined __arm64__
434
435 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
436 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
437 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
438
439 # if defined __arm64__ /* 64-bit */
440
441 /* See sys/arm64/include/ucontext.h. */
442
443 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.mc_gpregs.gp_sp
444
445 # elif defined __arm__ || defined __armhf__ /* 32-bit */
446
447 /* See sys/arm/include/ucontext.h. */
448
449 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[_REG_SP]
450
451 # endif
452
453 # else
454
455 /* On FreeBSD 12, both of these approaches work. On FreeBSD derivatives, the
456 first one has more chances to work. */
457 # if 1
458 /* Use signal handlers without SA_SIGINFO. */
459
460 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, void *addr
461 # define SIGSEGV_FAULT_ADDRESS addr
462 # define SIGSEGV_FAULT_CONTEXT scp
463
464 /* See sys/x86/include/signal.h. */
465
466 # if defined __x86_64__
467 /* 64 bit registers */
468
469 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
470
471 # elif defined __i386__
472 /* 32 bit registers */
473
474 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
475
476 # endif
477
478 # else
479 /* Use signal handlers with SA_SIGINFO. */
480
481 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp
482 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
483 # define SIGSEGV_FAULT_CONTEXT ((struct sigcontext *) scp)
484 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
485
486 /* See sys/x86/include/signal.h. */
487
488 # if defined __x86_64__
489 /* 64 bit registers */
490
491 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_rsp
492
493 # elif defined __i386__
494 /* 32 bit registers */
495
496 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_esp
497
498 # endif
499
500 # endif
501
502 # endif
503
504 #endif
505
506 #if defined __NetBSD__ /* NetBSD */
507
508 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
509 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
510 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
511 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
512
513 /* _UC_MACHINE_SP is a platform independent macro.
514 Defined in <machine/mcontext.h>, see
515 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/$arch/include/mcontext.h
516 Supported on alpha, amd64, i386, ia64, m68k, mips, powerpc, sparc since
517 NetBSD 2.0.
518 On i386, _UC_MACHINE_SP is the same as ->uc_mcontext.__gregs[_REG_UESP],
519 and apparently the same value as ->uc_mcontext.__gregs[_REG_ESP]. */
520 # ifdef _UC_MACHINE_SP
521 # define SIGSEGV_FAULT_STACKPOINTER _UC_MACHINE_SP ((ucontext_t *) ucp)
522 # endif
523
524 #endif
525
526 #if defined __OpenBSD__ /* OpenBSD */
527
528 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, struct sigcontext *scp
529 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
530 # define SIGSEGV_FAULT_CONTEXT scp
531 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
532
533 # if defined __alpha__
534
535 /* See the definition of 'struct sigcontext' in
536 openbsd-src/sys/arch/alpha/include/signal.h. */
537
538 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
539
540 # elif defined __arm__ || defined __armhf__
541
542 /* See the definition of 'struct sigcontext' in
543 openbsd-src/sys/arch/arm/include/signal.h. */
544
545 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_usr_sp
546
547 # elif defined __hppa__ || defined __hppa64__
548
549 /* See the definition of 'struct sigcontext' in
550 openbsd-src/sys/arch/hppa/include/signal.h
551 and
552 openbsd-src/sys/arch/hppa64/include/signal.h. */
553
554 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
555
556 # elif defined __x86_64__
557 /* 64 bit registers */
558
559 /* See the definition of 'struct sigcontext' in
560 openbsd-src/sys/arch/amd64/include/signal.h. */
561
562 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
563
564 # elif defined __i386__
565 /* 32 bit registers */
566
567 /* See the definition of 'struct sigcontext' in
568 openbsd-src/sys/arch/i386/include/signal.h. */
569
570 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
571
572 # elif defined __m68k__
573
574 /* See the definition of 'struct sigcontext' in
575 openbsd-src/sys/arch/m68k/include/signal.h. */
576
577 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
578
579 # elif defined __m88k__
580
581 /* See the definition of 'struct sigcontext' in
582 openbsd-src/sys/arch/m88k/include/signal.h
583 and the definition of 'struct reg' in
584 openbsd-src/sys/arch/m88k/include/reg.h. */
585
586 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
587 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[31]
588 # else
589 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs.r[31]
590 # endif
591
592 # elif defined __mips__ || defined __mipsn32__ || defined __mips64__
593
594 /* See the definition of 'struct sigcontext' in
595 openbsd-src/sys/arch/mips64/include/signal.h. */
596
597 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
598
599 # elif defined __powerpc64__
600
601 /* See the definition of 'struct sigcontext' in
602 openbsd-src/sys/arch/powerpc64/include/signal.h. */
603
604 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
605
606 # elif defined __powerpc__
607
608 /* See the definition of 'struct sigcontext' and 'struct trapframe' in
609 openbsd-src/sys/arch/powerpc/include/signal.h. */
610
611 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_frame.fixreg[1]
612
613 # elif defined __sh__
614
615 /* See the definition of 'struct sigcontext' in
616 openbsd-src/sys/arch/sh/include/signal.h
617 and the definition of 'struct reg' in
618 openbsd-src/sys/arch/sh/include/reg.h. */
619
620 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
621 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg[20-15]
622 # else
623 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg.r_r15
624 # endif
625
626 # elif defined __sparc__ || defined __sparc64__
627
628 /* See the definition of 'struct sigcontext' in
629 openbsd-src/sys/arch/sparc/include/signal.h
630 and
631 openbsd-src/sys/arch/sparc64/include/signal.h. */
632
633 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
634
635 # elif defined __vax__
636
637 /* See the definition of 'struct sigcontext' in
638 openbsd-src/sys/arch/vax/include/signal.h. */
639
640 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
641
642 # endif
643
644 #endif
645
646 #if (defined __APPLE__ && defined __MACH__) /* macOS */
647
648 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
649 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
650 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
651 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
652
653 # if defined __x86_64__
654
655 /* See the definitions of
656 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
657 - 'struct __darwin_mcontext64' in <i386/_mcontext.h>, and
658 - 'struct __darwin_x86_thread_state64' in <mach/i386/_structs.h>. */
659 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__rsp
660
661 # elif defined __i386__
662
663 /* See the definitions of
664 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
665 - 'struct __darwin_mcontext32' in <i386/_mcontext.h>, and
666 - 'struct __darwin_i386_thread_state' in <mach/i386/_structs.h>. */
667 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__esp
668
669 # elif defined __arm64__
670
671 /* See the definitions of
672 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
673 - 'struct __darwin_mcontext64' in <arm/_mcontext.h>, and
674 - 'struct __darwin_arm_thread_state64' in <mach/arm/_structs.h>. */
675 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__sp
676
677 # elif defined __powerpc__
678
679 /* See the definitions of
680 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_structs.h>,
681 - 'struct __darwin_mcontext' in <ppc/_structs.h>, and
682 - 'struct __darwin_ppc_thread_state' in <mach/ppc/_structs.h>. */
683 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__r1
684
685 # endif
686
687 #endif
688
689 #if defined _AIX /* AIX */
690
691 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
692 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
693 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
694 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
695
696 # if defined __powerpc__ || defined __powerpc64__
697 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.jmp_context.gpr[1]
698 # endif
699
700 #endif
701
702 #if defined __sgi /* IRIX */
703
704 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp
705 # define SIGSEGV_FAULT_ADDRESS (unsigned long) scp->sc_badvaddr
706 # define SIGSEGV_FAULT_CONTEXT scp
707
708 # if defined __mips__ || defined __mipsn32__ || defined __mips64__
709 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
710 # endif
711
712 #endif
713
714 #if defined __sun /* Solaris */
715
716 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
717 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
718 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
719 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
720
721 # if defined __x86_64__
722 /* 64 bit registers */
723
724 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_RSP]
725
726 # elif defined __i386__
727 /* 32 bit registers */
728
729 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[ESP]
730
731 # elif defined __sparc__ || defined __sparc64__
732
733 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_O6]
734
735 # if SOLARIS11
736
737 /* On Solaris 11.3/SPARC, both in 32-bit and 64-bit mode, when catching
738 stack overflow, the fault address is correct the first time, but is zero
739 or near zero the second time.
740 'truss tests/test-sigsegv-catch-stackoverflow1' shows it:
741
742 In 32-bit mode:
743
744 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
745 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
746 Received signal #11, SIGSEGV [caught]
747 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
748 then
749 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
750 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
751 Received signal #11, SIGSEGV [caught]
752 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
753
754 In 64-bit mode:
755
756 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
757 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
758 Received signal #11, SIGSEGV [caught]
759 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
760 then
761 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
762 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
763 Received signal #11, SIGSEGV [caught]
764 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
765 */
766 # define BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
767
768 # endif
769
770 # endif
771
772 #endif
773
774 #if defined __CYGWIN__ /* Cygwin */
775
776 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
777 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
778 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
779 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
780
781 /* See the definition of 'ucontext_t' in <sys/ucontext.h> and
782 of 'struct __mcontext' in <cygwin/signal.h>. */
783 # if defined __x86_64__
784 /* 64 bit registers */
785 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
786 # elif defined __i386__
787 /* 32 bit registers */
788 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
789 # endif
790
791 #endif
792
793 #if defined __HAIKU__ /* Haiku */
794
795 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
796 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
797 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
798 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
799
800 # if defined __x86_64__
801 /* 64 bit registers */
802
803 /* See the definition of 'ucontext_t' in <signal.h> and
804 of 'struct vregs' in <arch/x86_64/signal.h>. */
805
806 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
807
808 # elif defined __i386__
809 /* 32 bit registers */
810
811 /* See the definition of 'ucontext_t' in <signal.h> and
812 of 'struct vregs' in <arch/x86/signal.h>. */
813
814 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
815
816 # endif
817
818 #endif
819
820 /* ========================================================================== */
821
822 /* List of signals that are sent when an invalid virtual memory address
823 is accessed, or when the stack overflows. */
824 #if defined __GNU__ \
825 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
826 || defined __NetBSD__ || defined __OpenBSD__ \
827 || (defined __APPLE__ && defined __MACH__)
828 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
829 { int var; var = SIGSEGV; { body } var = SIGBUS; { body } }
830 #else
831 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
832 { int var; var = SIGSEGV; { body } }
833 #endif
834
835 /* ========================================================================== */
836
837 /* Determine the virtual memory area of a given address. */
838 #include "stackvma.h"
839
840 /* ========================================================================== */
841
842 /* On the average Unix platform, we define
843
844 HAVE_SIGSEGV_RECOVERY
845 if there is a fault-*.h include file which defines
846 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
847
848 HAVE_STACK_OVERFLOW_RECOVERY
849 if HAVE_SIGALTSTACK is set and
850 at least two of the following are true:
851 A) There is a fault-*.h include file which defines
852 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
853 B) There is a fault-*.h include file which defines
854 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_STACKPOINTER.
855 C) There is a stackvma-*.c, other than stackvma-none.c, which
856 defines sigsegv_get_vma.
857
858 Why? Obviously, to catch stack overflow, we need an alternate signal
859 stack; this requires kernel support. But we also need to distinguish
860 (with a reasonable confidence) a stack overflow from a regular SIGSEGV.
861 If we have A) and B), we use the
862 Heuristic AB: If the fault address is near the stack pointer, it's a
863 stack overflow.
864 If we have A) and C), we use the
865 Heuristic AC: If the fault address is near and beyond the bottom of
866 the stack's virtual memory area, it's a stack overflow.
867 If we have B) and C), we use the
868 Heuristic BC: If the stack pointer is near the bottom of the stack's
869 virtual memory area, it's a stack overflow.
870 This heuristic comes in two flavours: On OSes which let the stack's
871 VMA grow continuously, we determine the bottom by use of getrlimit().
872 On OSes which preallocate the stack's VMA with its maximum size
873 (like BeOS), we use the stack's VMA directly.
874 */
875
876 #if HAVE_SIGSEGV_RECOVERY \
877 && !(defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS)
878 # error "You need to define SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS before you can define HAVE_SIGSEGV_RECOVERY."
879 #endif
880 #if !HAVE_SIGSEGV_RECOVERY \
881 && (defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS) \
882 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__))
883 # if __GNUC__ || (__clang_major__ >= 4)
884 # warning "You can define HAVE_SIGSEGV_RECOVERY on this platform."
885 # else
886 # error "You can define HAVE_SIGSEGV_RECOVERY on this platform."
887 # endif
888 #endif
889
890 #if HAVE_STACK_OVERFLOW_RECOVERY \
891 && !(defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2)
892 # error "You need to define two of SIGSEGV_FAULT_ADDRESS, SIGSEGV_FAULT_STACKPOINTER, HAVE_STACKVMA, before you can define HAVE_STACK_OVERFLOW_RECOVERY."
893 #endif
894 #if !HAVE_STACK_OVERFLOW_RECOVERY \
895 && (defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2) \
896 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__)) \
897 && !(defined __NetBSD__ && (defined __sparc__ || defined __sparc64__))
898 # if __GNUC__ || (__clang_major__ >= 4)
899 # warning "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
900 # else
901 # error "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
902 # endif
903 #endif
904
905 /* ========================================================================== */
906
907 #if HAVE_STACK_OVERFLOW_RECOVERY
908
909 /* ======= Leaving a signal handler executing on the alternate stack ======= */
910
911 /* Platform dependent:
912 Leaving a signal handler executing on the alternate stack. */
913 static void sigsegv_reset_onstack_flag (void);
914
915 /* -------------------------- leave-sigaltstack.c -------------------------- */
916
917 # if defined __GNU__ \
918 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
919 || defined __NetBSD__ || defined __OpenBSD__
920
921 static void
922 sigsegv_reset_onstack_flag (void)
923 {
924 stack_t ss;
925
926 if (sigaltstack (NULL, &ss) >= 0)
927 {
928 ss.ss_flags &= ~SS_ONSTACK;
929 sigaltstack (&ss, NULL);
930 }
931 }
932
933 /* --------------------------- leave-setcontext.c --------------------------- */
934
935 # elif defined __sgi || defined __sun /* IRIX, Solaris */
936
937 # include <ucontext.h>
938
939 static void
940 sigsegv_reset_onstack_flag (void)
941 {
942 ucontext_t uc;
943
944 if (getcontext (&uc) >= 0)
945 /* getcontext returns twice. We are interested in the returned context
946 only the first time, i.e. when the SS_ONSTACK bit is set. */
947 if (uc.uc_stack.ss_flags & SS_ONSTACK)
948 {
949 uc.uc_stack.ss_flags &= ~SS_ONSTACK;
950 /* Note that setcontext() does not refill uc. Therefore if
951 setcontext() keeps SS_ONSTACK set in the kernel, either
952 setcontext() will return -1 or getcontext() will return a
953 second time, with the SS_ONSTACK bit being cleared. */
954 setcontext (&uc);
955 }
956 }
957
958 /* ------------------------------ leave-nop.c ------------------------------ */
959
960 # else
961
962 static void
963 sigsegv_reset_onstack_flag (void)
964 {
965 /* Nothing to do. sigaltstack() simply looks at the stack pointer,
966 therefore SS_ONSTACK is not sticky. */
967 }
968
969 # endif
970
971 /* ========================================================================== */
972
973 # if HAVE_STACKVMA
974
975 /* Address of the last byte belonging to the stack vma. */
976 static uintptr_t stack_top = 0;
977
978 /* Needs to be called once only. */
979 static void
980 remember_stack_top (void *some_variable_on_stack)
981 {
982 struct vma_struct vma;
983
984 if (sigsegv_get_vma ((uintptr_t) some_variable_on_stack, &vma) >= 0)
985 stack_top = vma.end - 1;
986 }
987
988 # endif /* HAVE_STACKVMA */
989
990 static stackoverflow_handler_t stk_user_handler = (stackoverflow_handler_t)NULL;
991 static uintptr_t stk_extra_stack;
992 static size_t stk_extra_stack_size;
993
994 #endif /* HAVE_STACK_OVERFLOW_RECOVERY */
995
996 #if HAVE_SIGSEGV_RECOVERY
997
998 /* User's SIGSEGV handler. */
999 static sigsegv_handler_t user_handler = (sigsegv_handler_t)NULL;
1000
1001 #endif /* HAVE_SIGSEGV_RECOVERY */
1002
1003
1004 /* Our SIGSEGV handler, with OS dependent argument list. */
1005
1006 #if HAVE_SIGSEGV_RECOVERY
1007
1008 static void
1009 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
1010 {
1011 void *address = (void *) (SIGSEGV_FAULT_ADDRESS);
1012
1013 # if HAVE_STACK_OVERFLOW_RECOVERY
1014 # if !(HAVE_STACKVMA || defined SIGSEGV_FAULT_STACKPOINTER)
1015 #error "Insufficient heuristics for detecting a stack overflow. Either define CFG_STACKVMA and HAVE_STACKVMA correctly, or define SIGSEGV_FAULT_STACKPOINTER correctly, or undefine HAVE_STACK_OVERFLOW_RECOVERY!"
1016 # endif
1017
1018 /* Call user's handler. */
1019 if (user_handler && (*user_handler) (address, 0))
1020 {
1021 /* Handler successful. */
1022 }
1023 else
1024 {
1025 /* Handler declined responsibility. */
1026
1027 /* Did the user install a stack overflow handler? */
1028 if (stk_user_handler)
1029 {
1030 /* See whether it was a stack overflow. If so, longjump away. */
1031 # ifdef SIGSEGV_FAULT_STACKPOINTER
1032 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
1033 # ifdef __ia64
1034 uintptr_t old_bsp = (uintptr_t) (SIGSEGV_FAULT_BSP_POINTER);
1035 # endif
1036 # endif
1037
1038 # if HAVE_STACKVMA
1039 /* Were we able to determine the stack top? */
1040 if (stack_top)
1041 {
1042 /* Determine stack bounds. */
1043 int saved_errno;
1044 struct vma_struct vma;
1045 int ret;
1046
1047 saved_errno = errno;
1048 ret = sigsegv_get_vma (stack_top, &vma);
1049 errno = saved_errno;
1050 if (ret >= 0)
1051 {
1052 # ifndef BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
1053 /* Heuristic AC: If the fault_address is nearer to the stack
1054 segment's [start,end] than to the previous segment, we
1055 consider it a stack overflow.
1056 In the case of IA-64, we know that the previous segment
1057 is the up-growing bsp segment, and either of the two
1058 stacks can overflow. */
1059 uintptr_t addr = (uintptr_t) address;
1060
1061 # ifdef __ia64
1062 if (addr >= vma.prev_end && addr <= vma.end - 1)
1063 # else
1064 # if STACK_DIRECTION < 0
1065 if (addr >= vma.start
1066 ? (addr <= vma.end - 1)
1067 : vma.is_near_this (addr, &vma))
1068 # else
1069 if (addr <= vma.end - 1
1070 ? (addr >= vma.start)
1071 : vma.is_near_this (addr, &vma))
1072 # endif
1073 # endif
1074 {
1075 # else /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
1076 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
1077 /* Heuristic BC: If the stack size has reached its maximal size,
1078 and old_sp is near the low end, we consider it a stack
1079 overflow. */
1080 struct rlimit rl;
1081
1082 saved_errno = errno;
1083 ret = getrlimit (RLIMIT_STACK, &rl);
1084 errno = saved_errno;
1085 if (ret >= 0)
1086 {
1087 uintptr_t current_stack_size = vma.end - vma.start;
1088 uintptr_t max_stack_size = rl.rlim_cur;
1089 if (current_stack_size <= max_stack_size + 4096
1090 && max_stack_size <= current_stack_size + 4096
1091 # else
1092 {
1093 if (1
1094 # endif
1095 # ifdef SIGSEGV_FAULT_STACKPOINTER
1096 /* Heuristic BC: If we know old_sp, and it is neither
1097 near the low end, nor in the alternate stack, then
1098 it's probably not a stack overflow. */
1099 && ((old_sp >= stk_extra_stack
1100 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1101 # if STACK_DIRECTION < 0
1102 || (old_sp <= vma.start + 4096
1103 && vma.start <= old_sp + 4096))
1104 # else
1105 || (old_sp <= vma.end + 4096
1106 && vma.end <= old_sp + 4096))
1107 # endif
1108 # endif
1109 )
1110 # endif /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
1111 # else /* !HAVE_STACKVMA */
1112 /* Heuristic AB: If the fault address is near the stack pointer,
1113 it's a stack overflow. */
1114 uintptr_t addr = (uintptr_t) address;
1115
1116 if ((addr <= old_sp + 4096 && old_sp <= addr + 4096)
1117 # ifdef __ia64
1118 || (addr <= old_bsp + 4096 && old_bsp <= addr + 4096)
1119 # endif
1120 )
1121 {
1122 {
1123 {
1124 # endif /* !HAVE_STACKVMA */
1125 {
1126 # ifdef SIGSEGV_FAULT_STACKPOINTER
1127 int emergency =
1128 (old_sp >= stk_extra_stack
1129 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1130 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1131 # else
1132 int emergency = 0;
1133 stackoverflow_context_t context = (void *) 0;
1134 # endif
1135 /* Call user's handler. */
1136 (*stk_user_handler) (emergency, context);
1137 }
1138 }
1139 }
1140 }
1141 }
1142 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1143
1144 if (user_handler && (*user_handler) (address, 1))
1145 {
1146 /* Handler successful. */
1147 }
1148 else
1149 {
1150 /* Handler declined responsibility for real. */
1151
1152 /* Remove ourselves and dump core. */
1153 SIGSEGV_FOR_ALL_SIGNALS (signo, signal (signo, SIG_DFL);)
1154 }
1155
1156 # if HAVE_STACK_OVERFLOW_RECOVERY
1157 }
1158 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1159 }
1160
1161 #elif HAVE_STACK_OVERFLOW_RECOVERY
1162
1163 static void
1164 # ifdef SIGSEGV_FAULT_STACKPOINTER
1165 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
1166 # else
1167 sigsegv_handler (int sig)
1168 # endif
1169 {
1170 # if !((HAVE_GETRLIMIT && defined RLIMIT_STACK) || defined SIGSEGV_FAULT_STACKPOINTER)
1171 # error "Insufficient heuristics for detecting a stack overflow. Either define SIGSEGV_FAULT_STACKPOINTER correctly, or undefine HAVE_STACK_OVERFLOW_RECOVERY!"
1172 # endif
1173
1174 /* Did the user install a handler? */
1175 if (stk_user_handler)
1176 {
1177 /* See whether it was a stack overflow. If so, longjump away. */
1178 # ifdef SIGSEGV_FAULT_STACKPOINTER
1179 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
1180 # endif
1181
1182 /* Were we able to determine the stack top? */
1183 if (stack_top)
1184 {
1185 /* Determine stack bounds. */
1186 int saved_errno;
1187 struct vma_struct vma;
1188 int ret;
1189
1190 saved_errno = errno;
1191 ret = sigsegv_get_vma (stack_top, &vma);
1192 errno = saved_errno;
1193 if (ret >= 0)
1194 {
1195 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
1196 /* Heuristic BC: If the stack size has reached its maximal size,
1197 and old_sp is near the low end, we consider it a stack
1198 overflow. */
1199 struct rlimit rl;
1200
1201 saved_errno = errno;
1202 ret = getrlimit (RLIMIT_STACK, &rl);
1203 errno = saved_errno;
1204 if (ret >= 0)
1205 {
1206 uintptr_t current_stack_size = vma.end - vma.start;
1207 uintptr_t max_stack_size = rl.rlim_cur;
1208 if (current_stack_size <= max_stack_size + 4096
1209 && max_stack_size <= current_stack_size + 4096
1210 # else
1211 {
1212 if (1
1213 # endif
1214 # ifdef SIGSEGV_FAULT_STACKPOINTER
1215 /* Heuristic BC: If we know old_sp, and it is neither
1216 near the low end, nor in the alternate stack, then
1217 it's probably not a stack overflow. */
1218 && ((old_sp >= stk_extra_stack
1219 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1220 # if STACK_DIRECTION < 0
1221 || (old_sp <= vma.start + 4096
1222 && vma.start <= old_sp + 4096))
1223 # else
1224 || (old_sp <= vma.end + 4096
1225 && vma.end <= old_sp + 4096))
1226 # endif
1227 # endif
1228 )
1229 {
1230 # ifdef SIGSEGV_FAULT_STACKPOINTER
1231 int emergency =
1232 (old_sp >= stk_extra_stack
1233 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1234 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1235 # else
1236 int emergency = 0;
1237 stackoverflow_context_t context = (void *) 0;
1238 # endif
1239 /* Call user's handler. */
1240 (*stk_user_handler)(emergency,context);
1241 }
1242 }
1243 }
1244 }
1245 }
1246
1247 /* Remove ourselves and dump core. */
1248 SIGSEGV_FOR_ALL_SIGNALS (signo, signal (signo, SIG_DFL);)
1249 }
1250
1251 #endif
1252
1253
1254 #if HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY
1255
1256 static void
1257 install_for (int sig)
1258 {
1259 struct sigaction action;
1260
1261 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1262 action.sa_sigaction = (void (*) (int, siginfo_t *, void *)) &sigsegv_handler;
1263 # else
1264 action.sa_handler = (void (*) (int)) &sigsegv_handler;
1265 # endif
1266 /* Block most signals while SIGSEGV is being handled. */
1267 /* Signals SIGKILL, SIGSTOP cannot be blocked. */
1268 /* Signals SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU are not blocked because
1269 dealing with these signals seems dangerous. */
1270 /* Signals SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGTRAP, SIGIOT, SIGEMT, SIGBUS,
1271 SIGSYS, SIGSTKFLT are not blocked because these are synchronous signals,
1272 which may require immediate intervention, otherwise the process may
1273 starve. */
1274 sigemptyset (&action.sa_mask);
1275 # ifdef SIGHUP
1276 sigaddset (&action.sa_mask,SIGHUP);
1277 # endif
1278 # ifdef SIGINT
1279 sigaddset (&action.sa_mask,SIGINT);
1280 # endif
1281 # ifdef SIGQUIT
1282 sigaddset (&action.sa_mask,SIGQUIT);
1283 # endif
1284 # ifdef SIGPIPE
1285 sigaddset (&action.sa_mask,SIGPIPE);
1286 # endif
1287 # ifdef SIGALRM
1288 sigaddset (&action.sa_mask,SIGALRM);
1289 # endif
1290 # ifdef SIGTERM
1291 sigaddset (&action.sa_mask,SIGTERM);
1292 # endif
1293 # ifdef SIGUSR1
1294 sigaddset (&action.sa_mask,SIGUSR1);
1295 # endif
1296 # ifdef SIGUSR2
1297 sigaddset (&action.sa_mask,SIGUSR2);
1298 # endif
1299 # ifdef SIGCHLD
1300 sigaddset (&action.sa_mask,SIGCHLD);
1301 # endif
1302 # ifdef SIGCLD
1303 sigaddset (&action.sa_mask,SIGCLD);
1304 # endif
1305 # ifdef SIGURG
1306 sigaddset (&action.sa_mask,SIGURG);
1307 # endif
1308 # ifdef SIGIO
1309 sigaddset (&action.sa_mask,SIGIO);
1310 # endif
1311 # ifdef SIGPOLL
1312 sigaddset (&action.sa_mask,SIGPOLL);
1313 # endif
1314 # ifdef SIGXCPU
1315 sigaddset (&action.sa_mask,SIGXCPU);
1316 # endif
1317 # ifdef SIGXFSZ
1318 sigaddset (&action.sa_mask,SIGXFSZ);
1319 # endif
1320 # ifdef SIGVTALRM
1321 sigaddset (&action.sa_mask,SIGVTALRM);
1322 # endif
1323 # ifdef SIGPROF
1324 sigaddset (&action.sa_mask,SIGPROF);
1325 # endif
1326 # ifdef SIGPWR
1327 sigaddset (&action.sa_mask,SIGPWR);
1328 # endif
1329 # ifdef SIGLOST
1330 sigaddset (&action.sa_mask,SIGLOST);
1331 # endif
1332 # ifdef SIGWINCH
1333 sigaddset (&action.sa_mask,SIGWINCH);
1334 # endif
1335 /* Note that sigaction() implicitly adds sig itself to action.sa_mask. */
1336 /* Ask the OS to provide a structure siginfo_t to the handler. */
1337 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1338 action.sa_flags = SA_SIGINFO;
1339 # else
1340 action.sa_flags = 0;
1341 # endif
1342 # if HAVE_STACK_OVERFLOW_RECOVERY && HAVE_SIGALTSTACK /* not BeOS */
1343 /* Work around Linux 2.2.5 bug: If SA_ONSTACK is specified but sigaltstack()
1344 has not been called, the kernel will busy loop, eating CPU time. So
1345 avoid setting SA_ONSTACK until the user has requested stack overflow
1346 handling. */
1347 if (stk_user_handler)
1348 action.sa_flags |= SA_ONSTACK;
1349 # endif
1350 sigaction (sig, &action, (struct sigaction *) NULL);
1351 }
1352
1353 #endif /* HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY */
1354
1355 int
1356 sigsegv_install_handler (sigsegv_handler_t handler)
1357 {
1358 #if HAVE_SIGSEGV_RECOVERY
1359 user_handler = handler;
1360
1361 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1362
1363 return 0;
1364 #else
1365 return -1;
1366 #endif
1367 }
1368
1369 void
1370 sigsegv_deinstall_handler (void)
1371 {
1372 #if HAVE_SIGSEGV_RECOVERY
1373 user_handler = (sigsegv_handler_t)NULL;
1374
1375 # if HAVE_STACK_OVERFLOW_RECOVERY
1376 if (!stk_user_handler)
1377 # endif
1378 {
1379 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1380 }
1381 #endif
1382 }
1383
1384 int
1385 sigsegv_leave_handler (void (*continuation) (void*, void*, void*),
1386 void* cont_arg1, void* cont_arg2, void* cont_arg3)
1387 {
1388 #if HAVE_STACK_OVERFLOW_RECOVERY
1389 /*
1390 * Reset the system's knowledge that we are executing on the alternate
1391 * stack. If we didn't do that, siglongjmp would be needed instead of
1392 * longjmp to leave the signal handler.
1393 */
1394 sigsegv_reset_onstack_flag ();
1395 #endif
1396 (*continuation) (cont_arg1, cont_arg2, cont_arg3);
1397 return 1;
1398 }
1399
1400 int
1401 stackoverflow_install_handler (stackoverflow_handler_t handler,
1402 void *extra_stack, size_t extra_stack_size)
1403 {
1404 #if HAVE_STACK_OVERFLOW_RECOVERY
1405 # if HAVE_STACKVMA
1406 if (!stack_top)
1407 {
1408 int dummy;
1409 remember_stack_top (&dummy);
1410 if (!stack_top)
1411 return -1;
1412 }
1413 # endif
1414
1415 stk_user_handler = handler;
1416 stk_extra_stack = (uintptr_t) extra_stack;
1417 stk_extra_stack_size = extra_stack_size;
1418 {
1419 stack_t ss;
1420 # if SIGALTSTACK_SS_REVERSED
1421 ss.ss_sp = (char *) extra_stack + extra_stack_size - sizeof (void *);
1422 ss.ss_size = extra_stack_size - sizeof (void *);
1423 # else
1424 ss.ss_sp = extra_stack;
1425 ss.ss_size = extra_stack_size;
1426 # endif
1427 ss.ss_flags = 0; /* no SS_DISABLE */
1428 if (sigaltstack (&ss, (stack_t*)0) < 0)
1429 return -1;
1430 }
1431
1432 /* Install the signal handlers with SA_ONSTACK. */
1433 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1434 return 0;
1435 #else
1436 return -1;
1437 #endif
1438 }
1439
1440 void
1441 stackoverflow_deinstall_handler (void)
1442 {
1443 #if HAVE_STACK_OVERFLOW_RECOVERY
1444 stk_user_handler = (stackoverflow_handler_t) NULL;
1445
1446 # if HAVE_SIGSEGV_RECOVERY
1447 if (user_handler)
1448 {
1449 /* Reinstall the signal handlers without SA_ONSTACK, to avoid Linux
1450 bug. */
1451 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1452 }
1453 else
1454 # endif
1455 {
1456 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1457 }
1458
1459 {
1460 stack_t ss;
1461 ss.ss_flags = SS_DISABLE;
1462 if (sigaltstack (&ss, (stack_t *) 0) < 0)
1463 perror ("gnulib sigsegv (stackoverflow_deinstall_handler)");
1464 }
1465 #endif
1466 }