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, int code, struct sigcontext *scp
365 # define SIGSEGV_FAULT_ADDRESS (unsigned long) code
366 # define SIGSEGV_FAULT_CONTEXT scp
367
368 # if defined __i386__
369
370 /* scp points to a 'struct sigcontext' (defined in
371 glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h).
372 The registers of this struct get pushed on the stack through
373 gnumach/i386/i386/locore.S:trapall. */
374 /* Both sc_esp and sc_uesp appear to have the same value.
375 It appears more reliable to use sc_uesp because it is labelled as
376 "old esp, if trapped from user". */
377 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_uesp
378
379 # endif
380
381 #endif
382
383 #if defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ /* GNU/kFreeBSD, FreeBSD */
384
385 # if defined __arm__ || defined __armhf__ || defined __arm64__
386
387 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
388 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
389 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
390
391 # if defined __arm64__ /* 64-bit */
392
393 /* See sys/arm64/include/ucontext.h. */
394
395 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.mc_gpregs.gp_sp
396
397 # elif defined __arm__ || defined __armhf__ /* 32-bit */
398
399 /* See sys/arm/include/ucontext.h. */
400
401 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[_REG_SP]
402
403 # endif
404
405 # else
406
407 /* On FreeBSD 12, both of these approaches work. On FreeBSD derivatives, the
408 first one has more chances to work. */
409 # if 1
410 /* Use signal handlers without SA_SIGINFO. */
411
412 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, void *addr
413 # define SIGSEGV_FAULT_ADDRESS addr
414 # define SIGSEGV_FAULT_CONTEXT scp
415
416 /* See sys/x86/include/signal.h. */
417
418 # if defined __x86_64__
419 /* 64 bit registers */
420
421 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
422
423 # elif defined __i386__
424 /* 32 bit registers */
425
426 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
427
428 # endif
429
430 # else
431 /* Use signal handlers with SA_SIGINFO. */
432
433 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp
434 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
435 # define SIGSEGV_FAULT_CONTEXT ((struct sigcontext *) scp)
436 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
437
438 /* See sys/x86/include/signal.h. */
439
440 # if defined __x86_64__
441 /* 64 bit registers */
442
443 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_rsp
444
445 # elif defined __i386__
446 /* 32 bit registers */
447
448 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_esp
449
450 # endif
451
452 # endif
453
454 # endif
455
456 #endif
457
458 #if defined __NetBSD__ /* NetBSD */
459
460 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
461 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
462 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
463 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
464
465 /* _UC_MACHINE_SP is a platform independent macro.
466 Defined in <machine/mcontext.h>, see
467 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/$arch/include/mcontext.h
468 Supported on alpha, amd64, i386, ia64, m68k, mips, powerpc, sparc since
469 NetBSD 2.0.
470 On i386, _UC_MACHINE_SP is the same as ->uc_mcontext.__gregs[_REG_UESP],
471 and apparently the same value as ->uc_mcontext.__gregs[_REG_ESP]. */
472 # ifdef _UC_MACHINE_SP
473 # define SIGSEGV_FAULT_STACKPOINTER _UC_MACHINE_SP ((ucontext_t *) ucp)
474 # endif
475
476 #endif
477
478 #if defined __OpenBSD__ /* OpenBSD */
479
480 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, struct sigcontext *scp
481 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
482 # define SIGSEGV_FAULT_CONTEXT scp
483 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
484
485 # if defined __alpha__
486
487 /* See the definition of 'struct sigcontext' in
488 openbsd-src/sys/arch/alpha/include/signal.h. */
489
490 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
491
492 # elif defined __arm__ || defined __armhf__
493
494 /* See the definition of 'struct sigcontext' in
495 openbsd-src/sys/arch/arm/include/signal.h. */
496
497 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_usr_sp
498
499 # elif defined __hppa__ || defined __hppa64__
500
501 /* See the definition of 'struct sigcontext' in
502 openbsd-src/sys/arch/hppa/include/signal.h
503 and
504 openbsd-src/sys/arch/hppa64/include/signal.h. */
505
506 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
507
508 # elif defined __x86_64__
509 /* 64 bit registers */
510
511 /* See the definition of 'struct sigcontext' in
512 openbsd-src/sys/arch/amd64/include/signal.h. */
513
514 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
515
516 # elif defined __i386__
517 /* 32 bit registers */
518
519 /* See the definition of 'struct sigcontext' in
520 openbsd-src/sys/arch/i386/include/signal.h. */
521
522 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
523
524 # elif defined __m68k__
525
526 /* See the definition of 'struct sigcontext' in
527 openbsd-src/sys/arch/m68k/include/signal.h. */
528
529 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
530
531 # elif defined __m88k__
532
533 /* See the definition of 'struct sigcontext' in
534 openbsd-src/sys/arch/m88k/include/signal.h
535 and the definition of 'struct reg' in
536 openbsd-src/sys/arch/m88k/include/reg.h. */
537
538 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
539 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[31]
540 # else
541 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs.r[31]
542 # endif
543
544 # elif defined __mips__ || defined __mipsn32__ || defined __mips64__
545
546 /* See the definition of 'struct sigcontext' in
547 openbsd-src/sys/arch/mips64/include/signal.h. */
548
549 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
550
551 # elif defined __powerpc64__
552
553 /* See the definition of 'struct sigcontext' in
554 openbsd-src/sys/arch/powerpc64/include/signal.h. */
555
556 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
557
558 # elif defined __powerpc__
559
560 /* See the definition of 'struct sigcontext' and 'struct trapframe' in
561 openbsd-src/sys/arch/powerpc/include/signal.h. */
562
563 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_frame.fixreg[1]
564
565 # elif defined __sh__
566
567 /* See the definition of 'struct sigcontext' in
568 openbsd-src/sys/arch/sh/include/signal.h
569 and the definition of 'struct reg' in
570 openbsd-src/sys/arch/sh/include/reg.h. */
571
572 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
573 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg[20-15]
574 # else
575 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg.r_r15
576 # endif
577
578 # elif defined __sparc__ || defined __sparc64__
579
580 /* See the definition of 'struct sigcontext' in
581 openbsd-src/sys/arch/sparc/include/signal.h
582 and
583 openbsd-src/sys/arch/sparc64/include/signal.h. */
584
585 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
586
587 # elif defined __vax__
588
589 /* See the definition of 'struct sigcontext' in
590 openbsd-src/sys/arch/vax/include/signal.h. */
591
592 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
593
594 # endif
595
596 #endif
597
598 #if (defined __APPLE__ && defined __MACH__) /* macOS */
599
600 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
601 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
602 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
603 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
604
605 # if defined __x86_64__
606
607 /* See the definitions of
608 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
609 - 'struct __darwin_mcontext64' in <i386/_mcontext.h>, and
610 - 'struct __darwin_x86_thread_state64' in <mach/i386/_structs.h>. */
611 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__rsp
612
613 # elif defined __i386__
614
615 /* See the definitions of
616 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
617 - 'struct __darwin_mcontext32' in <i386/_mcontext.h>, and
618 - 'struct __darwin_i386_thread_state' in <mach/i386/_structs.h>. */
619 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__esp
620
621 # elif defined __arm64__
622
623 /* See the definitions of
624 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
625 - 'struct __darwin_mcontext64' in <arm/_mcontext.h>, and
626 - 'struct __darwin_arm_thread_state64' in <mach/arm/_structs.h>. */
627 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__sp
628
629 # elif defined __powerpc__
630
631 /* See the definitions of
632 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_structs.h>,
633 - 'struct __darwin_mcontext' in <ppc/_structs.h>, and
634 - 'struct __darwin_ppc_thread_state' in <mach/ppc/_structs.h>. */
635 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__r1
636
637 # endif
638
639 #endif
640
641 #if defined _AIX /* AIX */
642
643 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
644 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
645 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
646 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
647
648 # if defined __powerpc__ || defined __powerpc64__
649 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.jmp_context.gpr[1]
650 # endif
651
652 #endif
653
654 #if defined __sgi /* IRIX */
655
656 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp
657 # define SIGSEGV_FAULT_ADDRESS (unsigned long) scp->sc_badvaddr
658 # define SIGSEGV_FAULT_CONTEXT scp
659
660 # if defined __mips__ || defined __mipsn32__ || defined __mips64__
661 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
662 # endif
663
664 #endif
665
666 #if defined __sun /* Solaris */
667
668 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
669 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
670 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
671 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
672
673 # if defined __x86_64__
674 /* 64 bit registers */
675
676 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_RSP]
677
678 # elif defined __i386__
679 /* 32 bit registers */
680
681 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[ESP]
682
683 # elif defined __sparc__ || defined __sparc64__
684
685 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_O6]
686
687 # if SOLARIS11
688
689 /* On Solaris 11.3/SPARC, both in 32-bit and 64-bit mode, when catching
690 stack overflow, the fault address is correct the first time, but is zero
691 or near zero the second time.
692 'truss tests/test-sigsegv-catch-stackoverflow1' shows it:
693
694 In 32-bit mode:
695
696 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
697 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
698 Received signal #11, SIGSEGV [caught]
699 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
700 then
701 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
702 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
703 Received signal #11, SIGSEGV [caught]
704 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
705
706 In 64-bit mode:
707
708 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
709 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
710 Received signal #11, SIGSEGV [caught]
711 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
712 then
713 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
714 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
715 Received signal #11, SIGSEGV [caught]
716 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
717 */
718 # define BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
719
720 # endif
721
722 # endif
723
724 #endif
725
726 #if defined __CYGWIN__ /* Cygwin */
727
728 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
729 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
730 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
731 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
732
733 /* See the definition of 'ucontext_t' in <sys/ucontext.h> and
734 of 'struct __mcontext' in <cygwin/signal.h>. */
735 # if defined __x86_64__
736 /* 64 bit registers */
737 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
738 # elif defined __i386__
739 /* 32 bit registers */
740 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
741 # endif
742
743 #endif
744
745 #if defined __HAIKU__ /* Haiku */
746
747 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
748 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
749 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
750 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
751
752 # if defined __x86_64__
753 /* 64 bit registers */
754
755 /* See the definition of 'ucontext_t' in <signal.h> and
756 of 'struct vregs' in <arch/x86_64/signal.h>. */
757
758 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
759
760 # elif defined __i386__
761 /* 32 bit registers */
762
763 /* See the definition of 'ucontext_t' in <signal.h> and
764 of 'struct vregs' in <arch/x86/signal.h>. */
765
766 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
767
768 # endif
769
770 #endif
771
772 /* ========================================================================== */
773
774 /* List of signals that are sent when an invalid virtual memory address
775 is accessed, or when the stack overflows. */
776 #if defined __GNU__ \
777 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
778 || defined __NetBSD__ || defined __OpenBSD__ \
779 || (defined __APPLE__ && defined __MACH__)
780 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
781 { int var; var = SIGSEGV; { body } var = SIGBUS; { body } }
782 #else
783 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
784 { int var; var = SIGSEGV; { body } }
785 #endif
786
787 /* ========================================================================== */
788
789 /* Determine the virtual memory area of a given address. */
790 #include "stackvma.h"
791
792 /* ========================================================================== */
793
794 /* On the average Unix platform, we define
795
796 HAVE_SIGSEGV_RECOVERY
797 if there is a fault-*.h include file which defines
798 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
799
800 HAVE_STACK_OVERFLOW_RECOVERY
801 if HAVE_SIGALTSTACK is set and
802 at least two of the following are true:
803 A) There is a fault-*.h include file which defines
804 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
805 B) There is a fault-*.h include file which defines
806 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_STACKPOINTER.
807 C) There is a stackvma-*.c, other than stackvma-none.c, which
808 defines sigsegv_get_vma.
809
810 Why? Obviously, to catch stack overflow, we need an alternate signal
811 stack; this requires kernel support. But we also need to distinguish
812 (with a reasonable confidence) a stack overflow from a regular SIGSEGV.
813 If we have A) and B), we use the
814 Heuristic AB: If the fault address is near the stack pointer, it's a
815 stack overflow.
816 If we have A) and C), we use the
817 Heuristic AC: If the fault address is near and beyond the bottom of
818 the stack's virtual memory area, it's a stack overflow.
819 If we have B) and C), we use the
820 Heuristic BC: If the stack pointer is near the bottom of the stack's
821 virtual memory area, it's a stack overflow.
822 This heuristic comes in two flavours: On OSes which let the stack's
823 VMA grow continuously, we determine the bottom by use of getrlimit().
824 On OSes which preallocate the stack's VMA with its maximum size
825 (like BeOS), we use the stack's VMA directly.
826 */
827
828 #if HAVE_SIGSEGV_RECOVERY \
829 && !(defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS)
830 # error "You need to define SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS before you can define HAVE_SIGSEGV_RECOVERY."
831 #endif
832 #if !HAVE_SIGSEGV_RECOVERY \
833 && (defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS) \
834 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__))
835 # if __GNUC__ || (__clang_major__ >= 4)
836 # warning "You can define HAVE_SIGSEGV_RECOVERY on this platform."
837 # else
838 # error "You can define HAVE_SIGSEGV_RECOVERY on this platform."
839 # endif
840 #endif
841
842 #if HAVE_STACK_OVERFLOW_RECOVERY \
843 && !(defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2)
844 # error "You need to define two of SIGSEGV_FAULT_ADDRESS, SIGSEGV_FAULT_STACKPOINTER, HAVE_STACKVMA, before you can define HAVE_STACK_OVERFLOW_RECOVERY."
845 #endif
846 #if !HAVE_STACK_OVERFLOW_RECOVERY \
847 && (defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2) \
848 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__)) \
849 && !(defined __NetBSD__ && (defined __sparc__ || defined __sparc64__))
850 # if __GNUC__ || (__clang_major__ >= 4)
851 # warning "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
852 # else
853 # error "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
854 # endif
855 #endif
856
857 /* ========================================================================== */
858
859 #if HAVE_STACK_OVERFLOW_RECOVERY
860
861 /* ======= Leaving a signal handler executing on the alternate stack ======= */
862
863 /* Platform dependent:
864 Leaving a signal handler executing on the alternate stack. */
865 static void sigsegv_reset_onstack_flag (void);
866
867 /* -------------------------- leave-sigaltstack.c -------------------------- */
868
869 # if defined __GNU__ \
870 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
871 || defined __NetBSD__ || defined __OpenBSD__
872
873 static void
874 sigsegv_reset_onstack_flag (void)
875 {
876 stack_t ss;
877
878 if (sigaltstack (NULL, &ss) >= 0)
879 {
880 ss.ss_flags &= ~SS_ONSTACK;
881 sigaltstack (&ss, NULL);
882 }
883 }
884
885 /* --------------------------- leave-setcontext.c --------------------------- */
886
887 # elif defined __sgi || defined __sun /* IRIX, Solaris */
888
889 # include <ucontext.h>
890
891 static void
892 sigsegv_reset_onstack_flag (void)
893 {
894 ucontext_t uc;
895
896 if (getcontext (&uc) >= 0)
897 /* getcontext returns twice. We are interested in the returned context
898 only the first time, i.e. when the SS_ONSTACK bit is set. */
899 if (uc.uc_stack.ss_flags & SS_ONSTACK)
900 {
901 uc.uc_stack.ss_flags &= ~SS_ONSTACK;
902 /* Note that setcontext() does not refill uc. Therefore if
903 setcontext() keeps SS_ONSTACK set in the kernel, either
904 setcontext() will return -1 or getcontext() will return a
905 second time, with the SS_ONSTACK bit being cleared. */
906 setcontext (&uc);
907 }
908 }
909
910 /* ------------------------------ leave-nop.c ------------------------------ */
911
912 # else
913
914 static void
915 sigsegv_reset_onstack_flag (void)
916 {
917 /* Nothing to do. sigaltstack() simply looks at the stack pointer,
918 therefore SS_ONSTACK is not sticky. */
919 }
920
921 # endif
922
923 /* ========================================================================== */
924
925 # if HAVE_STACKVMA
926
927 /* Address of the last byte belonging to the stack vma. */
928 static uintptr_t stack_top = 0;
929
930 /* Needs to be called once only. */
931 static void
932 remember_stack_top (void *some_variable_on_stack)
933 {
934 struct vma_struct vma;
935
936 if (sigsegv_get_vma ((uintptr_t) some_variable_on_stack, &vma) >= 0)
937 stack_top = vma.end - 1;
938 }
939
940 # endif /* HAVE_STACKVMA */
941
942 static stackoverflow_handler_t stk_user_handler = (stackoverflow_handler_t)NULL;
943 static uintptr_t stk_extra_stack;
944 static size_t stk_extra_stack_size;
945
946 #endif /* HAVE_STACK_OVERFLOW_RECOVERY */
947
948 #if HAVE_SIGSEGV_RECOVERY
949
950 /* User's SIGSEGV handler. */
951 static sigsegv_handler_t user_handler = (sigsegv_handler_t)NULL;
952
953 #endif /* HAVE_SIGSEGV_RECOVERY */
954
955
956 /* Our SIGSEGV handler, with OS dependent argument list. */
957
958 #if HAVE_SIGSEGV_RECOVERY
959
960 static void
961 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
962 {
963 void *address = (void *) (SIGSEGV_FAULT_ADDRESS);
964
965 # if HAVE_STACK_OVERFLOW_RECOVERY
966 # if !(HAVE_STACKVMA || defined SIGSEGV_FAULT_STACKPOINTER)
967 #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!"
968 # endif
969
970 /* Call user's handler. */
971 if (user_handler && (*user_handler) (address, 0))
972 {
973 /* Handler successful. */
974 }
975 else
976 {
977 /* Handler declined responsibility. */
978
979 /* Did the user install a stack overflow handler? */
980 if (stk_user_handler)
981 {
982 /* See whether it was a stack overflow. If so, longjump away. */
983 # ifdef SIGSEGV_FAULT_STACKPOINTER
984 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
985 # ifdef __ia64
986 uintptr_t old_bsp = (uintptr_t) (SIGSEGV_FAULT_BSP_POINTER);
987 # endif
988 # endif
989
990 # if HAVE_STACKVMA
991 /* Were we able to determine the stack top? */
992 if (stack_top)
993 {
994 /* Determine stack bounds. */
995 int saved_errno;
996 struct vma_struct vma;
997 int ret;
998
999 saved_errno = errno;
1000 ret = sigsegv_get_vma (stack_top, &vma);
1001 errno = saved_errno;
1002 if (ret >= 0)
1003 {
1004 # ifndef BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
1005 /* Heuristic AC: If the fault_address is nearer to the stack
1006 segment's [start,end] than to the previous segment, we
1007 consider it a stack overflow.
1008 In the case of IA-64, we know that the previous segment
1009 is the up-growing bsp segment, and either of the two
1010 stacks can overflow. */
1011 uintptr_t addr = (uintptr_t) address;
1012
1013 # ifdef __ia64
1014 if (addr >= vma.prev_end && addr <= vma.end - 1)
1015 # else
1016 # if STACK_DIRECTION < 0
1017 if (addr >= vma.start
1018 ? (addr <= vma.end - 1)
1019 : vma.is_near_this (addr, &vma))
1020 # else
1021 if (addr <= vma.end - 1
1022 ? (addr >= vma.start)
1023 : vma.is_near_this (addr, &vma))
1024 # endif
1025 # endif
1026 {
1027 # else /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
1028 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
1029 /* Heuristic BC: If the stack size has reached its maximal size,
1030 and old_sp is near the low end, we consider it a stack
1031 overflow. */
1032 struct rlimit rl;
1033
1034 saved_errno = errno;
1035 ret = getrlimit (RLIMIT_STACK, &rl);
1036 errno = saved_errno;
1037 if (ret >= 0)
1038 {
1039 uintptr_t current_stack_size = vma.end - vma.start;
1040 uintptr_t max_stack_size = rl.rlim_cur;
1041 if (current_stack_size <= max_stack_size + 4096
1042 && max_stack_size <= current_stack_size + 4096
1043 # else
1044 {
1045 if (1
1046 # endif
1047 # ifdef SIGSEGV_FAULT_STACKPOINTER
1048 /* Heuristic BC: If we know old_sp, and it is neither
1049 near the low end, nor in the alternate stack, then
1050 it's probably not a stack overflow. */
1051 && ((old_sp >= stk_extra_stack
1052 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1053 # if STACK_DIRECTION < 0
1054 || (old_sp <= vma.start + 4096
1055 && vma.start <= old_sp + 4096))
1056 # else
1057 || (old_sp <= vma.end + 4096
1058 && vma.end <= old_sp + 4096))
1059 # endif
1060 # endif
1061 )
1062 # endif /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
1063 # else /* !HAVE_STACKVMA */
1064 /* Heuristic AB: If the fault address is near the stack pointer,
1065 it's a stack overflow. */
1066 uintptr_t addr = (uintptr_t) address;
1067
1068 if ((addr <= old_sp + 4096 && old_sp <= addr + 4096)
1069 # ifdef __ia64
1070 || (addr <= old_bsp + 4096 && old_bsp <= addr + 4096)
1071 # endif
1072 )
1073 {
1074 {
1075 {
1076 # endif /* !HAVE_STACKVMA */
1077 {
1078 # ifdef SIGSEGV_FAULT_STACKPOINTER
1079 int emergency =
1080 (old_sp >= stk_extra_stack
1081 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1082 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1083 # else
1084 int emergency = 0;
1085 stackoverflow_context_t context = (void *) 0;
1086 # endif
1087 /* Call user's handler. */
1088 (*stk_user_handler) (emergency, context);
1089 }
1090 }
1091 }
1092 }
1093 }
1094 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1095
1096 if (user_handler && (*user_handler) (address, 1))
1097 {
1098 /* Handler successful. */
1099 }
1100 else
1101 {
1102 /* Handler declined responsibility for real. */
1103
1104 /* Remove ourselves and dump core. */
1105 SIGSEGV_FOR_ALL_SIGNALS (signo, signal (signo, SIG_DFL);)
1106 }
1107
1108 # if HAVE_STACK_OVERFLOW_RECOVERY
1109 }
1110 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1111 }
1112
1113 #elif HAVE_STACK_OVERFLOW_RECOVERY
1114
1115 static void
1116 # ifdef SIGSEGV_FAULT_STACKPOINTER
1117 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
1118 # else
1119 sigsegv_handler (int sig)
1120 # endif
1121 {
1122 # if !((HAVE_GETRLIMIT && defined RLIMIT_STACK) || defined SIGSEGV_FAULT_STACKPOINTER)
1123 # error "Insufficient heuristics for detecting a stack overflow. Either define SIGSEGV_FAULT_STACKPOINTER correctly, or undefine HAVE_STACK_OVERFLOW_RECOVERY!"
1124 # endif
1125
1126 /* Did the user install a handler? */
1127 if (stk_user_handler)
1128 {
1129 /* See whether it was a stack overflow. If so, longjump away. */
1130 # ifdef SIGSEGV_FAULT_STACKPOINTER
1131 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
1132 # endif
1133
1134 /* Were we able to determine the stack top? */
1135 if (stack_top)
1136 {
1137 /* Determine stack bounds. */
1138 int saved_errno;
1139 struct vma_struct vma;
1140 int ret;
1141
1142 saved_errno = errno;
1143 ret = sigsegv_get_vma (stack_top, &vma);
1144 errno = saved_errno;
1145 if (ret >= 0)
1146 {
1147 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
1148 /* Heuristic BC: If the stack size has reached its maximal size,
1149 and old_sp is near the low end, we consider it a stack
1150 overflow. */
1151 struct rlimit rl;
1152
1153 saved_errno = errno;
1154 ret = getrlimit (RLIMIT_STACK, &rl);
1155 errno = saved_errno;
1156 if (ret >= 0)
1157 {
1158 uintptr_t current_stack_size = vma.end - vma.start;
1159 uintptr_t max_stack_size = rl.rlim_cur;
1160 if (current_stack_size <= max_stack_size + 4096
1161 && max_stack_size <= current_stack_size + 4096
1162 # else
1163 {
1164 if (1
1165 # endif
1166 # ifdef SIGSEGV_FAULT_STACKPOINTER
1167 /* Heuristic BC: If we know old_sp, and it is neither
1168 near the low end, nor in the alternate stack, then
1169 it's probably not a stack overflow. */
1170 && ((old_sp >= stk_extra_stack
1171 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1172 # if STACK_DIRECTION < 0
1173 || (old_sp <= vma.start + 4096
1174 && vma.start <= old_sp + 4096))
1175 # else
1176 || (old_sp <= vma.end + 4096
1177 && vma.end <= old_sp + 4096))
1178 # endif
1179 # endif
1180 )
1181 {
1182 # ifdef SIGSEGV_FAULT_STACKPOINTER
1183 int emergency =
1184 (old_sp >= stk_extra_stack
1185 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1186 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1187 # else
1188 int emergency = 0;
1189 stackoverflow_context_t context = (void *) 0;
1190 # endif
1191 /* Call user's handler. */
1192 (*stk_user_handler)(emergency,context);
1193 }
1194 }
1195 }
1196 }
1197 }
1198
1199 /* Remove ourselves and dump core. */
1200 SIGSEGV_FOR_ALL_SIGNALS (signo, signal (signo, SIG_DFL);)
1201 }
1202
1203 #endif
1204
1205
1206 #if HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY
1207
1208 static void
1209 install_for (int sig)
1210 {
1211 struct sigaction action;
1212
1213 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1214 action.sa_sigaction = (void (*) (int, siginfo_t *, void *)) &sigsegv_handler;
1215 # else
1216 action.sa_handler = (void (*) (int)) &sigsegv_handler;
1217 # endif
1218 /* Block most signals while SIGSEGV is being handled. */
1219 /* Signals SIGKILL, SIGSTOP cannot be blocked. */
1220 /* Signals SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU are not blocked because
1221 dealing with these signals seems dangerous. */
1222 /* Signals SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGTRAP, SIGIOT, SIGEMT, SIGBUS,
1223 SIGSYS, SIGSTKFLT are not blocked because these are synchronous signals,
1224 which may require immediate intervention, otherwise the process may
1225 starve. */
1226 sigemptyset (&action.sa_mask);
1227 # ifdef SIGHUP
1228 sigaddset (&action.sa_mask,SIGHUP);
1229 # endif
1230 # ifdef SIGINT
1231 sigaddset (&action.sa_mask,SIGINT);
1232 # endif
1233 # ifdef SIGQUIT
1234 sigaddset (&action.sa_mask,SIGQUIT);
1235 # endif
1236 # ifdef SIGPIPE
1237 sigaddset (&action.sa_mask,SIGPIPE);
1238 # endif
1239 # ifdef SIGALRM
1240 sigaddset (&action.sa_mask,SIGALRM);
1241 # endif
1242 # ifdef SIGTERM
1243 sigaddset (&action.sa_mask,SIGTERM);
1244 # endif
1245 # ifdef SIGUSR1
1246 sigaddset (&action.sa_mask,SIGUSR1);
1247 # endif
1248 # ifdef SIGUSR2
1249 sigaddset (&action.sa_mask,SIGUSR2);
1250 # endif
1251 # ifdef SIGCHLD
1252 sigaddset (&action.sa_mask,SIGCHLD);
1253 # endif
1254 # ifdef SIGCLD
1255 sigaddset (&action.sa_mask,SIGCLD);
1256 # endif
1257 # ifdef SIGURG
1258 sigaddset (&action.sa_mask,SIGURG);
1259 # endif
1260 # ifdef SIGIO
1261 sigaddset (&action.sa_mask,SIGIO);
1262 # endif
1263 # ifdef SIGPOLL
1264 sigaddset (&action.sa_mask,SIGPOLL);
1265 # endif
1266 # ifdef SIGXCPU
1267 sigaddset (&action.sa_mask,SIGXCPU);
1268 # endif
1269 # ifdef SIGXFSZ
1270 sigaddset (&action.sa_mask,SIGXFSZ);
1271 # endif
1272 # ifdef SIGVTALRM
1273 sigaddset (&action.sa_mask,SIGVTALRM);
1274 # endif
1275 # ifdef SIGPROF
1276 sigaddset (&action.sa_mask,SIGPROF);
1277 # endif
1278 # ifdef SIGPWR
1279 sigaddset (&action.sa_mask,SIGPWR);
1280 # endif
1281 # ifdef SIGLOST
1282 sigaddset (&action.sa_mask,SIGLOST);
1283 # endif
1284 # ifdef SIGWINCH
1285 sigaddset (&action.sa_mask,SIGWINCH);
1286 # endif
1287 /* Note that sigaction() implicitly adds sig itself to action.sa_mask. */
1288 /* Ask the OS to provide a structure siginfo_t to the handler. */
1289 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1290 action.sa_flags = SA_SIGINFO;
1291 # else
1292 action.sa_flags = 0;
1293 # endif
1294 # if HAVE_STACK_OVERFLOW_RECOVERY && HAVE_SIGALTSTACK /* not BeOS */
1295 /* Work around Linux 2.2.5 bug: If SA_ONSTACK is specified but sigaltstack()
1296 has not been called, the kernel will busy loop, eating CPU time. So
1297 avoid setting SA_ONSTACK until the user has requested stack overflow
1298 handling. */
1299 if (stk_user_handler)
1300 action.sa_flags |= SA_ONSTACK;
1301 # endif
1302 sigaction (sig, &action, (struct sigaction *) NULL);
1303 }
1304
1305 #endif /* HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY */
1306
1307 int
1308 sigsegv_install_handler (sigsegv_handler_t handler)
1309 {
1310 #if HAVE_SIGSEGV_RECOVERY
1311 user_handler = handler;
1312
1313 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1314
1315 return 0;
1316 #else
1317 return -1;
1318 #endif
1319 }
1320
1321 void
1322 sigsegv_deinstall_handler (void)
1323 {
1324 #if HAVE_SIGSEGV_RECOVERY
1325 user_handler = (sigsegv_handler_t)NULL;
1326
1327 # if HAVE_STACK_OVERFLOW_RECOVERY
1328 if (!stk_user_handler)
1329 # endif
1330 {
1331 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1332 }
1333 #endif
1334 }
1335
1336 int
1337 sigsegv_leave_handler (void (*continuation) (void*, void*, void*),
1338 void* cont_arg1, void* cont_arg2, void* cont_arg3)
1339 {
1340 #if HAVE_STACK_OVERFLOW_RECOVERY
1341 /*
1342 * Reset the system's knowledge that we are executing on the alternate
1343 * stack. If we didn't do that, siglongjmp would be needed instead of
1344 * longjmp to leave the signal handler.
1345 */
1346 sigsegv_reset_onstack_flag ();
1347 #endif
1348 (*continuation) (cont_arg1, cont_arg2, cont_arg3);
1349 return 1;
1350 }
1351
1352 int
1353 stackoverflow_install_handler (stackoverflow_handler_t handler,
1354 void *extra_stack, size_t extra_stack_size)
1355 {
1356 #if HAVE_STACK_OVERFLOW_RECOVERY
1357 # if HAVE_STACKVMA
1358 if (!stack_top)
1359 {
1360 int dummy;
1361 remember_stack_top (&dummy);
1362 if (!stack_top)
1363 return -1;
1364 }
1365 # endif
1366
1367 stk_user_handler = handler;
1368 stk_extra_stack = (uintptr_t) extra_stack;
1369 stk_extra_stack_size = extra_stack_size;
1370 {
1371 stack_t ss;
1372 # if SIGALTSTACK_SS_REVERSED
1373 ss.ss_sp = (char *) extra_stack + extra_stack_size - sizeof (void *);
1374 ss.ss_size = extra_stack_size - sizeof (void *);
1375 # else
1376 ss.ss_sp = extra_stack;
1377 ss.ss_size = extra_stack_size;
1378 # endif
1379 ss.ss_flags = 0; /* no SS_DISABLE */
1380 if (sigaltstack (&ss, (stack_t*)0) < 0)
1381 return -1;
1382 }
1383
1384 /* Install the signal handlers with SA_ONSTACK. */
1385 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1386 return 0;
1387 #else
1388 return -1;
1389 #endif
1390 }
1391
1392 void
1393 stackoverflow_deinstall_handler (void)
1394 {
1395 #if HAVE_STACK_OVERFLOW_RECOVERY
1396 stk_user_handler = (stackoverflow_handler_t) NULL;
1397
1398 # if HAVE_SIGSEGV_RECOVERY
1399 if (user_handler)
1400 {
1401 /* Reinstall the signal handlers without SA_ONSTACK, to avoid Linux
1402 bug. */
1403 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1404 }
1405 else
1406 # endif
1407 {
1408 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1409 }
1410
1411 {
1412 stack_t ss;
1413 ss.ss_flags = SS_DISABLE;
1414 if (sigaltstack (&ss, (stack_t *) 0) < 0)
1415 perror ("gnulib sigsegv (stackoverflow_deinstall_handler)");
1416 }
1417 #endif
1418 }