1/* Page fault handling library. 2 Copyright (C) 1998-1999, 2002, 2004-2007 Bruno Haible <bruno@clisp.org> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software Foundation, 16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 18#ifndef _SIGSEGV_H 19#define _SIGSEGV_H 20 21@FAULT_CONTEXT_INCLUDE@ 22@FAULT_CONTEXT_INCLUDE2@ 23 24/* HAVE_SIGSEGV_RECOVERY 25 is defined if the system supports catching SIGSEGV. */ 26#if @HAVE_SIGSEGV_RECOVERY@ 27# define HAVE_SIGSEGV_RECOVERY 1 28#endif 29 30/* HAVE_STACK_OVERFLOW_RECOVERY 31 is defined if stack overflow can be caught. */ 32#if @HAVE_STACK_OVERFLOW_RECOVERY@ 33# define HAVE_STACK_OVERFLOW_RECOVERY 1 34#endif 35 36 37#ifdef __cplusplus 38extern "C" { 39#endif 40 41#define LIBSIGSEGV_VERSION 0x0205 /* version number: (major<<8) + minor */ 42extern int libsigsegv_version; /* Likewise */ 43 44/* -------------------------------------------------------------------------- */ 45 46/* 47 * The type of a global SIGSEGV handler. 48 * The fault address is passed as argument. 49 * The access type (read access or write access) is not passed; your handler 50 * has to know itself how to distinguish these two cases. 51 * The second argument is 0, meaning it could also be a stack overflow, or 1, 52 * meaning the handler should seriously try to fix the fault. 53 * The return value should be nonzero if the handler has done its job 54 * and no other handler should be called, or 0 if the handler declines 55 * responsibility for the given address. 56 */ 57typedef int (*sigsegv_handler_t) (void* fault_address, int serious); 58 59/* 60 * Installs a global SIGSEGV handler. 61 * This should be called once only, and it ignores any previously installed 62 * SIGSEGV handler. 63 * Returns 0 on success, or -1 if the system doesn't support catching SIGSEGV. 64 */ 65extern int sigsegv_install_handler (sigsegv_handler_t handler); 66 67/* 68 * Deinstalls the global SIGSEGV handler. 69 * This goes back to the state where no SIGSEGV handler is installed. 70 */ 71extern void sigsegv_deinstall_handler (void); 72 73/* 74 * Prepares leaving a SIGSEGV handler (through longjmp or similar means). 75 */ 76extern void sigsegv_leave_handler (void); 77 78/* 79 * The type of a context passed to a stack overflow handler. 80 * This type is system dependent; on some platforms it is an 'ucontext_t *', 81 * on some platforms it is a 'struct sigcontext *', on others merely an 82 * opaque 'void *'. 83 */ 84typedef @FAULT_CONTEXT@ *stackoverflow_context_t; 85 86/* 87 * The type of a stack overflow handler. 88 * Such a handler should perform a longjmp call in order to reduce the amount 89 * of stack needed. It must not return. 90 * The emergency argument is 0 when the stack could be repared, or 1 if the 91 * application should better save its state and exit now. 92 */ 93typedef void (*stackoverflow_handler_t) (int emergency, stackoverflow_context_t scp); 94 95/* 96 * Installs a stack overflow handler. 97 * The extra_stack argument is a pointer to a pre-allocated area used as a 98 * stack for executing the handler. It is typically allocated by use of 99 * `alloca' during `main'. Its size should be sufficiently large. 100 * The following code determines an appropriate size: 101 * #include <signal.h> 102 * #ifndef SIGSTKSZ / * glibc defines SIGSTKSZ for this purpose * / 103 * # define SIGSTKSZ 16384 / * on most platforms, 16 KB are sufficient * / 104 * #endif 105 * Returns 0 on success, or -1 if the system doesn't support catching stack 106 * overflow. 107 */ 108extern int stackoverflow_install_handler (stackoverflow_handler_t handler, 109 void* extra_stack, unsigned long extra_stack_size); 110 111/* 112 * Deinstalls the stack overflow handler. 113 */ 114extern void stackoverflow_deinstall_handler (void); 115 116/* -------------------------------------------------------------------------- */ 117 118/* 119 * The following structure and functions permit to define different SIGSEGV 120 * policies on different address ranges. 121 */ 122 123/* 124 * The type of a local SIGSEGV handler. 125 * The fault address is passed as argument. 126 * The second argument is fixed arbitrary user data. 127 * The return value should be nonzero if the handler has done its job 128 * and no other handler should be called, or 0 if the handler declines 129 * responsibility for the given address. 130 */ 131typedef int (*sigsegv_area_handler_t) (void* fault_address, void* user_arg); 132 133/* 134 * This structure represents a table of memory areas (address range intervals), 135 * with an local SIGSEGV handler for each. 136 */ 137typedef 138struct sigsegv_dispatcher { 139 void* tree; 140} 141sigsegv_dispatcher; 142 143/* 144 * Initializes a sigsegv_dispatcher structure. 145 */ 146extern void sigsegv_init (sigsegv_dispatcher* dispatcher); 147 148/* 149 * Adds a local SIGSEGV handler to a sigsegv_dispatcher structure. 150 * It will cover the interval [address..address+len-1]. 151 * Returns a "ticket" that can be used to remove the handler later. 152 */ 153extern void* sigsegv_register (sigsegv_dispatcher* dispatcher, 154 void* address, unsigned long len, 155 sigsegv_area_handler_t handler, void* handler_arg); 156 157/* 158 * Removes a local SIGSEGV handler. 159 */ 160extern void sigsegv_unregister (sigsegv_dispatcher* dispatcher, void* ticket); 161 162/* 163 * Call the local SIGSEGV handler responsible for the given fault address. 164 * Return the handler's return value. 0 means that no handler has been found, 165 * or that a handler was found but declined responsibility. 166 */ 167extern int sigsegv_dispatch (sigsegv_dispatcher* dispatcher, void* fault_address); 168 169/* -------------------------------------------------------------------------- */ 170 171#ifdef __cplusplus 172} 173#endif 174 175#endif /* _SIGSEGV_H */ 176