1 # Check prerequisites for compiling lib/c-stack.c.
3 # Copyright (C) 2002, 2003, 2004, 2008 Free Software Foundation, Inc.
4 # This file is free software; the Free Software Foundation
5 # gives unlimited permission to copy and/or distribute it,
6 # with or without modifications, as long as this notice is preserved.
8 # Written by Paul Eggert.
12 AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
13 [# for STACK_DIRECTION
14 AC_REQUIRE([AC_FUNC_ALLOCA])
15 AC_CHECK_FUNCS_ONCE([setrlimit])
16 AC_CHECK_HEADERS_ONCE([ucontext.h])
18 AC_CACHE_CHECK([for working C stack overflow detection],
19 ac_cv_sys_xsi_stack_overflow_heuristic,
25 # include <ucontext.h>
28 # include <sys/types.h>
29 # include <sys/time.h>
30 # include <sys/resource.h>
35 char buffer[SIGSTKSZ];
39 } alternate_signal_stack;
42 # define find_stack_direction(ptr) STACK_DIRECTION
45 find_stack_direction (char const *addr)
48 return (! addr ? find_stack_direction (&dummy)
49 : addr < &dummy ? 1 : -1);
54 segv_handler (int signo, siginfo_t *info, void *context)
56 if (0 < info->si_code)
58 /* For XSI heuristics to work, we need uc_stack to describe
59 the interrupted stack (as on Solaris), and not the
60 currently executing stack (as on Linux). */
61 ucontext_t const *user_context = context;
62 char const *stack_min = user_context->uc_stack.ss_sp;
63 size_t stack_size = user_context->uc_stack.ss_size;
64 char const *faulting_address = info->si_addr;
65 size_t s = faulting_address - stack_min;
66 size_t page_size = sysconf (_SC_PAGESIZE);
67 if (find_stack_direction (0) < 0)
69 if (s < stack_size + page_size)
84 st.ss_sp = alternate_signal_stack.buffer;
85 st.ss_size = sizeof alternate_signal_stack.buffer;
86 r = sigaltstack (&st, 0);
90 sigemptyset (&act.sa_mask);
91 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
92 act.sa_sigaction = segv_handler;
93 return sigaction (SIGSEGV, &act, 0);
101 return *p + recurse (array);
107 #if HAVE_SETRLIMIT && defined RLIMIT_STACK
108 /* Before starting the endless recursion, try to be friendly
109 to the user's machine. On some Linux 2.2.x systems, there
110 is no stack limit for user processes at all. We don't want
111 to kill such systems. */
113 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
114 setrlimit (RLIMIT_STACK, &rl);
118 return recurse ("\1");
121 [ac_cv_sys_xsi_stack_overflow_heuristic=yes],
122 [ac_cv_sys_xsi_stack_overflow_heuristic=no],
123 [ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])])
125 if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then
126 AC_DEFINE(HAVE_XSI_STACK_OVERFLOW_HEURISTIC, 1,
127 [Define to 1 if extending the stack slightly past the limit causes
128 a SIGSEGV, and an alternate stack can be established with sigaltstack,
129 and the signal handler is passed a context that specifies the
130 run time stack. This behavior is defined by POSIX 1003.1-2001
131 with the X/Open System Interface (XSI) option
132 and is a standardized way to implement a SEGV-based stack
133 overflow detection heuristic.])
137 AC_DEFUN([gl_PREREQ_C_STACK],
138 [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
139 AC_REQUIRE([gl_LIBSIGSEGV])
141 # for STACK_DIRECTION
142 AC_REQUIRE([AC_FUNC_ALLOCA])
144 AC_CHECK_FUNCS_ONCE([sigaltstack])
145 AC_CHECK_DECLS([sigaltstack], , , [#include <signal.h>])
147 AC_CHECK_HEADERS_ONCE([unistd.h ucontext.h])
149 AC_CHECK_MEMBERS([struct sigaction.sa_sigaction], , , [#include <signal.h>])
151 AC_CHECK_TYPES([stack_t], , , [#include <signal.h>])
153 dnl c-stack does not need -lsigsegv if the system has XSI heuristics.
154 if test "$gl_cv_lib_sigsegv" = yes \
155 && test $"ac_cv_sys_xsi_stack_overflow_heuristic" != yes ; then
156 AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
157 AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
161 AC_DEFUN([gl_C_STACK],
163 dnl Prerequisites of lib/c-stack.c.