(root)/
m4-1.4.19/
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  }