root/maint/gnulib/lib/sigsegv.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sigsegv_reset_onstack_flag
  2. sigsegv_reset_onstack_flag
  3. sigsegv_reset_onstack_flag
  4. remember_stack_top
  5. sigsegv_handler
  6. sigsegv_handler
  7. install_for
  8. sigsegv_install_handler
  9. sigsegv_deinstall_handler
  10. sigsegv_leave_handler
  11. stackoverflow_install_handler
  12. stackoverflow_deinstall_handler

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

/* [previous][next][first][last][top][bottom][index][help] */