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