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