Bump to m4 1.4.19
[platform/upstream/m4.git] / lib / sigsegv.c
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 }