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