1 # fault.m4 serial 5 (libsigsegv-2.2)
2 dnl Copyright (C) 2002-2003 Bruno Haible <bruno@clisp.org>
3 dnl This file is free software, distributed under the terms of the GNU
4 dnl General Public License. As a special exception to the GNU General
5 dnl Public License, this file may be distributed as part of a program
6 dnl that contains a configuration script generated by Autoconf, under
7 dnl the same distribution terms as the rest of that program.
9 dnl How to write a SIGSEGV handler with access to the fault address.
10 dnl SV_TRY_FAULT(KIND, CACHESYMBOL, KNOWN-SYSTEMS,
11 dnl INCLUDES, FAULT_HANDLER_ARGLIST, FAULT_ADDRESS, [INSTALLCODE])
12 AC_DEFUN([SV_TRY_FAULT], [
13 AC_REQUIRE([AC_PROG_CC])
14 AC_REQUIRE([AC_CANONICAL_HOST])
16 AC_CACHE_CHECK([whether a fault handler according to $1 works], [$2], [
22 # include <sys/signal.h>
25 #include <sys/types.h>
38 # define map_flags MAP_ANON | MAP_PRIVATE
39 #elif HAVE_MMAP_ANONYMOUS
41 # define map_flags MAP_ANONYMOUS | MAP_PRIVATE
42 #elif HAVE_MMAP_DEVZERO
44 # define map_flags MAP_FILE | MAP_PRIVATE
47 int handler_called = 0;
48 void sigsegv_handler ($5)
50 void *fault_address = (void *) ($6);
52 if (handler_called == 10)
54 if (fault_address != (void*)(page + 0x678))
56 if (mprotect ((void *) page, 0x10000, PROT_READ | PROT_WRITE) < 0)
59 void crasher (unsigned long p)
61 *(int *) (p + 0x678) = 42;
66 struct sigaction action;
68 #if !HAVE_MMAP_ANON && !HAVE_MMAP_ANONYMOUS && HAVE_MMAP_DEVZERO
69 zero_fd = open ("/dev/zero", O_RDONLY, 0644);
71 /* Setup some mmaped memory. */
73 /* HP-UX 10 mmap() often fails when given a hint. So give the OS complete
74 freedom about the address range. */
75 p = mmap ((void *) 0, 0x10000, PROT_READ | PROT_WRITE, map_flags, zero_fd, 0);
77 p = mmap ((void *) 0x12340000, 0x10000, PROT_READ | PROT_WRITE, map_flags, zero_fd, 0);
79 if (p == (void *)(-1))
81 page = (unsigned long) p;
82 /* Make it read-only. */
83 if (mprotect ((void *) page, 0x10000, PROT_READ) < 0)
85 /* Install the SIGSEGV handler. */
86 sigemptyset(&action.sa_mask);
88 action.sa_handler = (void (*) (int)) &sigsegv_handler;
91 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
92 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
93 /* The first write access should invoke the handler and then complete. */
95 /* The second write access should not invoke the handler. */
97 /* Check that the handler was called only once. */
98 if (handler_called != 1)
106 m4_if([$3], [], [], [[$3]) $2=yes ;;])
112 void sigsegv_handler ($5)
114 void *fault_address = (void *) ($6);
117 [[struct sigaction action;