c-stack.m4 revision 1.1.1.1 1 1.1 christos # Check prerequisites for compiling lib/c-stack.c.
2 1.1 christos
3 1.1 christos # Copyright (C) 2002 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos # This program is free software; you can redistribute it and/or modify
6 1.1 christos # it under the terms of the GNU General Public License as published by
7 1.1 christos # the Free Software Foundation; either version 2, or (at your option)
8 1.1 christos # any later version.
9 1.1 christos
10 1.1 christos # This program is distributed in the hope that it will be useful,
11 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 1.1 christos # GNU General Public License for more details.
14 1.1 christos
15 1.1 christos # You should have received a copy of the GNU General Public License
16 1.1 christos # along with this program; if not, write to the Free Software
17 1.1 christos # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 1.1 christos # 02111-1307, USA.
19 1.1 christos
20 1.1 christos AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
21 1.1 christos [# for STACK_DIRECTION
22 1.1 christos AC_REQUIRE([AC_FUNC_ALLOCA])
23 1.1 christos
24 1.1 christos AC_CACHE_CHECK([for working C stack overflow detection],
25 1.1 christos ac_cv_sys_xsi_stack_overflow_heuristic,
26 1.1 christos [AC_TRY_RUN(
27 1.1 christos [
28 1.1 christos #include <signal.h>
29 1.1 christos #include <ucontext.h>
30 1.1 christos
31 1.1 christos static union
32 1.1 christos {
33 1.1 christos char buffer[SIGSTKSZ];
34 1.1 christos long double ld;
35 1.1 christos uintmax_t u;
36 1.1 christos void *p;
37 1.1 christos } alternate_signal_stack;
38 1.1 christos
39 1.1 christos #if STACK_DIRECTION
40 1.1 christos # define find_stack_direction(ptr) STACK_DIRECTION
41 1.1 christos #else
42 1.1 christos static int
43 1.1 christos find_stack_direction (char const *addr)
44 1.1 christos {
45 1.1 christos char dummy;
46 1.1 christos return (! addr ? find_stack_direction (&dummy)
47 1.1 christos : addr < &dummy ? 1 : -1);
48 1.1 christos }
49 1.1 christos #endif
50 1.1 christos
51 1.1 christos static void
52 1.1 christos segv_handler (int signo, siginfo_t *info, void *context)
53 1.1 christos {
54 1.1 christos if (0 < info->si_code)
55 1.1 christos {
56 1.1 christos ucontext_t const *user_context = context;
57 1.1 christos char const *stack_min = user_context->uc_stack.ss_sp;
58 1.1 christos size_t stack_size = user_context->uc_stack.ss_size;
59 1.1 christos char const *faulting_address = info->si_addr;
60 1.1 christos size_t s = faulting_address - stack_min;
61 1.1 christos size_t page_size = sysconf (_SC_PAGESIZE);
62 1.1 christos if (find_stack_direction (0) < 0)
63 1.1 christos s += page_size;
64 1.1 christos if (s < stack_size + page_size)
65 1.1 christos _exit (0);
66 1.1 christos }
67 1.1 christos
68 1.1 christos _exit (1);
69 1.1 christos }
70 1.1 christos
71 1.1 christos static int
72 1.1 christos c_stack_action (void)
73 1.1 christos {
74 1.1 christos stack_t st;
75 1.1 christos struct sigaction act;
76 1.1 christos int r;
77 1.1 christos
78 1.1 christos st.ss_flags = 0;
79 1.1 christos st.ss_sp = alternate_signal_stack.buffer;
80 1.1 christos st.ss_size = sizeof alternate_signal_stack.buffer;
81 1.1 christos r = sigaltstack (&st, 0);
82 1.1 christos if (r != 0)
83 1.1 christos return r;
84 1.1 christos
85 1.1 christos sigemptyset (&act.sa_mask);
86 1.1 christos act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
87 1.1 christos act.sa_sigaction = segv_handler;
88 1.1 christos return sigaction (SIGSEGV, &act, 0);
89 1.1 christos }
90 1.1 christos
91 1.1 christos static int
92 1.1 christos recurse (char *p)
93 1.1 christos {
94 1.1 christos char array[500];
95 1.1 christos array[0] = 1;
96 1.1 christos return *p + recurse (array);
97 1.1 christos }
98 1.1 christos
99 1.1 christos int
100 1.1 christos main (void)
101 1.1 christos {
102 1.1 christos c_stack_action ();
103 1.1 christos return recurse ("\1");
104 1.1 christos }
105 1.1 christos ],
106 1.1 christos [ac_cv_sys_xsi_stack_overflow_heuristic=yes],
107 1.1 christos [ac_cv_sys_xsi_stack_overflow_heuristic=no],
108 1.1 christos [ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])])
109 1.1 christos
110 1.1 christos if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then
111 1.1 christos AC_DEFINE(HAVE_XSI_STACK_OVERFLOW_HEURISTIC, 1,
112 1.1 christos [Define to 1 if extending the stack slightly past the limit causes
113 1.1 christos a SIGSEGV, and an alternate stack can be established with sigaltstack,
114 1.1 christos and the signal handler is passed a context that specifies the
115 1.1 christos run time stack. This behavior is defined by POSIX 1003.1-2001
116 1.1 christos with the X/Open System Interface (XSI) option
117 1.1 christos and is a standardized way to implement a SEGV-based stack
118 1.1 christos overflow detection heuristic.])
119 1.1 christos fi])
120 1.1 christos
121 1.1 christos
122 1.1 christos AC_DEFUN([jm_PREREQ_C_STACK],
123 1.1 christos [AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])
124 1.1 christos AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
125 1.1 christos
126 1.1 christos # for STACK_DIRECTION
127 1.1 christos AC_REQUIRE([AC_FUNC_ALLOCA])
128 1.1 christos
129 1.1 christos AC_CHECK_HEADERS(unistd.h)
130 1.1 christos
131 1.1 christos AC_CHECK_TYPES([siginfo_t, stack_t], , , [#include <signal.h>])])
132