ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sigsegv.h
Revision: 1.14
Committed: 2010-07-27T22:52:33Z (14 years, 4 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
Changes since 1.13: +2 -1 lines
Log Message:
Fixing sigsegv on Mach x86_64 - possibly a hack; I'm not sure why the
address returned doesn't have that bit set already.

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * sigsegv.h - SIGSEGV signals support
3     *
4     * Derived from Bruno Haible's work on his SIGSEGV library for clisp
5     * <http://clisp.sourceforge.net/>
6     *
7 gbeauche 1.11 * Basilisk II (C) 1997-2008 Christian Bauer
8 gbeauche 1.1 *
9     * This program is free software; you can redistribute it and/or modify
10     * it under the terms of the GNU General Public License as published by
11     * the Free Software Foundation; either version 2 of the License, or
12     * (at your option) any later version.
13     *
14     * This program is distributed in the hope that it will be useful,
15     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17     * GNU General Public License for more details.
18     *
19     * You should have received a copy of the GNU General Public License
20     * along with this program; if not, write to the Free Software
21     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22     */
23    
24     #ifndef SIGSEGV_H
25     #define SIGSEGV_H
26    
27 gbeauche 1.10 #define SIGSEGV_MAJOR_VERSION 1
28     #define SIGSEGV_MINOR_VERSION 0
29     #define SIGSEGV_MICRO_VERSION 0
30    
31     #define SIGSEGV_CHECK_VERSION(MAJOR, MINOR, MICRO) \
32     (SIGSEGV_MAJOR_VERSION > (MAJOR) || \
33     (SIGSEGV_MAJOR_VERSION == (MAJOR) && SIGSEGV_MINOR_VERSION > (MINOR)) || \
34     (SIGSEGV_MAJOR_VERSION == (MAJOR) && SIGSEGV_MINOR_VERSION == (MINOR) && SIGSEGV_MICRO_VERSION >= (MICRO)))
35    
36 gbeauche 1.1 // Address type
37 gbeauche 1.10 typedef char *sigsegv_address_t;
38    
39     // SIGSEGV handler argument (forward declaration)
40 asvitkine 1.13
41     #if HAVE_MACH_EXCEPTIONS
42     #if defined(__APPLE__) && defined(__MACH__)
43     extern "C" {
44     #include <mach/mach.h>
45     #include <mach/mach_error.h>
46     }
47    
48     #ifdef __ppc__
49     #if __DARWIN_UNIX03 && defined _STRUCT_PPC_THREAD_STATE
50     #define MACH_FIELD_NAME(X) __CONCAT(__,X)
51     #endif
52     #define SIGSEGV_EXCEPTION_STATE_TYPE ppc_exception_state_t
53     #define SIGSEGV_EXCEPTION_STATE_FLAVOR PPC_EXCEPTION_STATE
54     #define SIGSEGV_EXCEPTION_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
55     #define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(dar)
56     #define SIGSEGV_THREAD_STATE_TYPE ppc_thread_state_t
57     #define SIGSEGV_THREAD_STATE_FLAVOR PPC_THREAD_STATE
58     #define SIGSEGV_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
59     #define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(srr0)
60     #define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction
61     #define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(srr0), (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(r0)
62     #endif
63     #ifdef __ppc64__
64     #if __DARWIN_UNIX03 && defined _STRUCT_PPC_THREAD_STATE64
65     #define MACH_FIELD_NAME(X) __CONCAT(__,X)
66     #endif
67     #define SIGSEGV_EXCEPTION_STATE_TYPE ppc_exception_state64_t
68     #define SIGSEGV_EXCEPTION_STATE_FLAVOR PPC_EXCEPTION_STATE64
69     #define SIGSEGV_EXCEPTION_STATE_COUNT PPC_EXCEPTION_STATE64_COUNT
70     #define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(dar)
71     #define SIGSEGV_THREAD_STATE_TYPE ppc_thread_state64_t
72     #define SIGSEGV_THREAD_STATE_FLAVOR PPC_THREAD_STATE64
73     #define SIGSEGV_THREAD_STATE_COUNT PPC_THREAD_STATE64_COUNT
74     #define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(srr0)
75     #define SIGSEGV_SKIP_INSTRUCTION powerpc_skip_instruction
76     #define SIGSEGV_REGISTER_FILE (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(srr0), (unsigned long *)&SIP->thr_state.MACH_FIELD_NAME(r0)
77     #endif
78     #ifdef __i386__
79     #if __DARWIN_UNIX03 && defined _STRUCT_X86_THREAD_STATE32
80     #define MACH_FIELD_NAME(X) __CONCAT(__,X)
81     #endif
82     #define SIGSEGV_EXCEPTION_STATE_TYPE i386_exception_state_t
83     #define SIGSEGV_EXCEPTION_STATE_FLAVOR i386_EXCEPTION_STATE
84     #define SIGSEGV_EXCEPTION_STATE_COUNT i386_EXCEPTION_STATE_COUNT
85     #define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(faultvaddr)
86     #define SIGSEGV_THREAD_STATE_TYPE i386_thread_state_t
87     #define SIGSEGV_THREAD_STATE_FLAVOR i386_THREAD_STATE
88     #define SIGSEGV_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT
89     #define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(eip)
90     #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
91     #define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(eax)) /* EAX is the first GPR we consider */
92 asvitkine 1.14 #define SIGSEGV_FAULT_ADDRESS_FAST code[1]
93 asvitkine 1.13 #endif
94     #ifdef __x86_64__
95     #if __DARWIN_UNIX03 && defined _STRUCT_X86_THREAD_STATE64
96     #define MACH_FIELD_NAME(X) __CONCAT(__,X)
97     #endif
98     #define SIGSEGV_EXCEPTION_STATE_TYPE x86_exception_state64_t
99     #define SIGSEGV_EXCEPTION_STATE_FLAVOR x86_EXCEPTION_STATE64
100     #define SIGSEGV_EXCEPTION_STATE_COUNT x86_EXCEPTION_STATE64_COUNT
101     #define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(faultvaddr)
102     #define SIGSEGV_THREAD_STATE_TYPE x86_thread_state64_t
103     #define SIGSEGV_THREAD_STATE_FLAVOR x86_THREAD_STATE64
104     #define SIGSEGV_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
105     #define SIGSEGV_FAULT_INSTRUCTION SIP->thr_state.MACH_FIELD_NAME(rip)
106     #define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
107     #define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */
108 asvitkine 1.14 #define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000)
109 asvitkine 1.13 #endif
110     #define SIGSEGV_FAULT_INSTRUCTION_FAST SIGSEGV_INVALID_ADDRESS
111     #define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, mach_exception_data_t code
112     #define SIGSEGV_FAULT_HANDLER_ARGS thread, code
113    
114     #endif
115     #endif
116    
117     struct sigsegv_info_t {
118     sigsegv_address_t addr;
119     sigsegv_address_t pc;
120     #ifdef HAVE_MACH_EXCEPTIONS
121     mach_port_t thread;
122     bool has_exc_state;
123     SIGSEGV_EXCEPTION_STATE_TYPE exc_state;
124     mach_msg_type_number_t exc_state_count;
125     bool has_thr_state;
126     SIGSEGV_THREAD_STATE_TYPE thr_state;
127     mach_msg_type_number_t thr_state_count;
128     #endif
129     };
130    
131 gbeauche 1.1
132 gbeauche 1.6 // SIGSEGV handler return state
133     enum sigsegv_return_t {
134     SIGSEGV_RETURN_SUCCESS,
135     SIGSEGV_RETURN_FAILURE,
136 gbeauche 1.12 SIGSEGV_RETURN_SKIP_INSTRUCTION
137 gbeauche 1.6 };
138    
139 gbeauche 1.1 // Type of a SIGSEGV handler. Returns boolean expressing successful operation
140 gbeauche 1.10 typedef sigsegv_return_t (*sigsegv_fault_handler_t)(sigsegv_info_t *sip);
141 gbeauche 1.4
142     // Type of a SIGSEGV state dump function
143 gbeauche 1.10 typedef void (*sigsegv_state_dumper_t)(sigsegv_info_t *sip);
144 gbeauche 1.1
145     // Install a SIGSEGV handler. Returns boolean expressing success
146 gbeauche 1.4 extern bool sigsegv_install_handler(sigsegv_fault_handler_t handler);
147 gbeauche 1.1
148     // Remove the user SIGSEGV handler, revert to default behavior
149     extern void sigsegv_uninstall_handler(void);
150 gbeauche 1.3
151     // Set callback function when we cannot handle the fault
152 gbeauche 1.4 extern void sigsegv_set_dump_state(sigsegv_state_dumper_t handler);
153 gbeauche 1.3
154 gbeauche 1.10 // Return the address of the invalid memory reference
155     extern sigsegv_address_t sigsegv_get_fault_address(sigsegv_info_t *sip);
156    
157     // Return the address of the instruction that caused the fault, or
158     // SIGSEGV_INVALID_ADDRESS if we could not retrieve this information
159     extern sigsegv_address_t sigsegv_get_fault_instruction_address(sigsegv_info_t *sip);
160    
161 gbeauche 1.1 // Define an address that is bound to be invalid for a program counter
162 gbeauche 1.10 const sigsegv_address_t SIGSEGV_INVALID_ADDRESS = (sigsegv_address_t)(-1UL);
163 gbeauche 1.1
164     #endif /* SIGSEGV_H */