Proper handling of -Werror=coverage-mismatch
[official-gcc.git] / libjava / include / s390-signal.h
blob4ca4c108864e60af79bc52fe98e3e9f5bbf0fb3b
1 // s390-signal.h - Catch runtime signals and turn them into exceptions
2 // on an s390 based Linux system.
4 /* Copyright (C) 2002, 2010 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10 details. */
13 #ifndef JAVA_SIGNAL_H
14 #define JAVA_SIGNAL_H 1
16 #include <signal.h>
17 #include <sys/syscall.h>
18 #include <ucontext.h>
19 #include <limits.h>
21 #define HANDLE_SEGV 1
22 #define HANDLE_FPE 1
24 #define SIGNAL_HANDLER(_name) \
25 static void _name (int, siginfo_t *_si __attribute__((unused)), \
26 ucontext_t *_uc __attribute__((unused)))
28 /* We no longer need to fiddle with the PSW address in the signal handler;
29 this is now all handled correctly in MD_FALLBACK_FRAME_STATE_FOR. */
30 #define MAKE_THROW_FRAME(_exception)
33 /* According to the JVM spec, "if the dividend is the negative integer
34 of the smallest magnitude and the divisor is -1, then overflow occurs
35 and the result is equal to the dividend. Despite the overflow, no
36 exception occurs".
38 We handle this by inspecting the instruction which generated the signal,
39 and if dividend and divisor are as above, we simply return from the signal
40 handler. This causes execution to continue after the instruction.
41 Before returning, we the set result registers as expected. */
42 #define UC_EXTENDED 0x00000001
44 #define HANDLE_DIVIDE_OVERFLOW \
45 do \
46 { \
47 unsigned char *_eip = (unsigned char *) \
48 __builtin_extract_return_addr (_si->si_addr); \
49 unsigned long *_regs = _uc->uc_mcontext.gregs; \
50 int _r1, _r2, _d2, _x2, _b2; \
51 struct \
52 { \
53 unsigned long int uc_flags; \
54 struct ucontext *uc_link; \
55 stack_t uc_stack; \
56 mcontext_t uc_mcontext; \
57 unsigned long sigmask[2]; \
58 unsigned long ext_regs[16]; \
59 } *_uc_ext = (typeof(_uc_ext))_uc; \
61 /* First, a couple of helper routines to decode instructions. */ \
62 struct _decode \
63 { \
64 /* Decode RR instruction format. */ \
65 static inline int _is_rr (unsigned char *_eip, \
66 unsigned char _op, \
67 int *_r1, int *_r2) \
68 { \
69 if (_eip[0] == _op) \
70 { \
71 *_r1 = _eip[1] >> 4; \
72 *_r2 = _eip[1] & 0xf; \
73 return 1; \
74 } \
75 return 0; \
76 } \
78 /* Decode RX instruction format. */ \
79 static inline int _is_rx (unsigned char *_eip, \
80 unsigned char _op, \
81 int *_r1, int *_d2, int *_x2, int *_b2) \
82 { \
83 if (_eip[0] == _op) \
84 { \
85 *_r1 = _eip[1] >> 4; \
86 *_x2 = _eip[1] & 0xf; \
87 *_b2 = _eip[2] >> 4; \
88 *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3]; \
89 return 1; \
90 } \
91 return 0; \
92 } \
94 /* Decode RRE instruction format. */ \
95 static inline int _is_rre (unsigned char *_eip, \
96 unsigned char _op1, unsigned char _op2,\
97 int *_r1, int *_r2) \
98 { \
99 if (_eip[0] == _op1 && _eip[1] == _op2) \
101 *_r1 = _eip[3] >> 4; \
102 *_r2 = _eip[3] & 0xf; \
103 return 1; \
105 return 0; \
108 /* Decode RXY instruction format. */ \
109 static inline int _is_rxy (unsigned char *_eip, \
110 unsigned char _op1, unsigned char _op2,\
111 int *_r1, int *_d2, int *_x2, int *_b2)\
113 if (_eip[0] == _op1 && _eip[5] == _op2) \
115 *_r1 = _eip[1] >> 4; \
116 *_x2 = _eip[1] & 0xf; \
117 *_b2 = _eip[2] >> 4; \
118 *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3] + (_eip[4] << 12); \
119 /* We have a 20-bit signed displacement. */ \
120 *_d2 = (*_d2 ^ 0x80000) - 0x80000; \
121 return 1; \
123 return 0; \
126 /* Compute effective address. */ \
127 static inline unsigned long _eff (unsigned long *_regs, \
128 long _d, int _x, int _b) \
130 return _d + (_x? _regs[_x] : 0) + (_b? _regs[_b] : 0); \
133 static inline int is_long_long_min_p (unsigned long *_regs, \
134 unsigned long *_ext_regs, \
135 int _r) \
137 return ((long long)_regs[_r] \
138 | (long long)_ext_regs[_r] << 32) == \
139 LONG_LONG_MIN; \
141 }; \
143 /* DR r1,r2 */ \
144 if (_decode::_is_rr (_eip, 0x1d, &_r1, &_r2) \
145 && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN \
146 && (int) _regs[_r2] == -1) \
148 _regs[_r1] &= ~0xffffffff; \
149 return; \
152 /* D r1,d2(x2,b2) */ \
153 if (_decode::_is_rx (_eip, 0x5d, &_r1, &_d2, &_x2, &_b2) \
154 && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN \
155 && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1) \
157 _regs[_r1] &= ~0xffffffff; \
158 return; \
161 /* DSGR r1,r2 */ \
162 if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2) \
163 && (long) _regs[_r1+1] == LONG_MIN \
164 && (long) _regs[_r2] == -1L) \
166 _regs[_r1] = 0; \
167 return; \
170 /* DSGFR r1,r2 */ \
171 if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2) \
172 && (long) _regs[_r1+1] == LONG_MIN \
173 && (int) _regs[_r2] == -1) \
175 _regs[_r1] = 0; \
176 return; \
179 /* DSG r1,d2(x2,b2) */ \
180 if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2) \
181 && (long) _regs[_r1+1] == LONG_MIN \
182 && *(long *) _decode::_eff (_regs, _d2, _x2, _b2) == -1L) \
184 _regs[_r1] = 0; \
185 return; \
188 /* DSGF r1,d2(x2,b2) */ \
189 if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2) \
190 && (long) _regs[_r1+1] == LONG_MIN \
191 && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1) \
193 _regs[_r1] = 0; \
194 return; \
197 /* The extended ucontext contains the upper halfs of the 64bit \
198 registers in 31bit applications. */ \
199 if (_uc->uc_flags & 1 == 1) \
201 /* DSGR r1,r2 */ \
202 if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2) \
203 && (int) _regs[_r2] == -1 \
204 && (int) _uc_ext->ext_regs[_r2] == -1 \
205 && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
206 _r1 + 1)) \
208 _regs[_r1] = 0; \
209 _uc_ext->ext_regs[_r1] = 0; \
210 return; \
213 /* DSGFR r1,r2 */ \
214 if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2) \
215 && (int) _regs[_r2] == -1 \
216 && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
217 _r1 + 1)) \
219 _regs[_r1] = 0; \
220 _uc_ext->ext_regs[_r1] = 0; \
221 return; \
224 /* DSG r1,d2(x2,b2) */ \
225 if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2) \
226 && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1 \
227 && *(int *) _decode::_eff (_regs, _d2 + 4, _x2, _b2) == -1 \
228 && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
229 _r1 + 1)) \
231 _regs[_r1] = 0; \
232 _uc_ext->ext_regs[_r1] = 0; \
233 return; \
236 /* DSGF r1,d2(x2,b2) */ \
237 if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2) \
238 && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1 \
239 && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs, \
240 _r1 + 1)) \
242 _regs[_r1] = 0; \
243 _uc_ext->ext_regs[_r1] = 0; \
244 return; \
248 while (0)
250 /* For an explanation why we cannot simply use sigaction to
251 install the handlers, see i386-signal.h. */
253 /* We use old_kernel_sigaction here because we're calling the kernel
254 directly rather than via glibc. The sigaction structure that the
255 syscall uses is a different shape from the one in userland and not
256 visible to us in a header file so we define it here. */
258 struct old_s390_kernel_sigaction {
259 void (*k_sa_handler) (int, siginfo_t *, ucontext_t *);
260 unsigned long k_sa_mask;
261 unsigned long k_sa_flags;
262 void (*sa_restorer) (void);
265 #define INIT_SEGV \
266 do \
268 struct old_s390_kernel_sigaction kact; \
269 kact.k_sa_handler = catch_segv; \
270 kact.k_sa_mask = 0; \
271 kact.k_sa_flags = SA_SIGINFO; \
272 syscall (SYS_sigaction, SIGSEGV, &kact, NULL); \
274 while (0)
276 #define INIT_FPE \
277 do \
279 struct old_s390_kernel_sigaction kact; \
280 kact.k_sa_handler = catch_fpe; \
281 kact.k_sa_mask = 0; \
282 kact.k_sa_flags = SA_SIGINFO; \
283 syscall (SYS_sigaction, SIGFPE, &kact, NULL); \
285 while (0)
287 #endif /* JAVA_SIGNAL_H */