1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 #ifndef SCM_UXTRAP_H
28 #define SCM_UXTRAP_H
29 
30 #include "os.h"
31 
32 /* Machine/OS-dependent section (long) */
33 
34 #if defined(hp9000s300) || defined(__hp9000s300)
35 
36 #include <sys/sysmacros.h>
37 #include <machine/sendsig.h>
38 #include <machine/reg.h>
39 
40 #define HAVE_SIGCONTEXT
41 #define SIGCONTEXT_ARG_T		struct full_sigcontext
42 #define SIGCONTEXT_NREGS		GPR_REGS /* Missing sp */
43 #define SIGCONTEXT_FIRST_REG(scp)	(&((scp)->fs_regs[GPR_START]))
44 #define SIGCONTEXT_SP(scp)		((scp)->fs_context.sc_sp)
45 #define SIGCONTEXT_PC(scp)		((scp)->fs_context.sc_pc)
46 #define SIGCONTEXT_RFREE(scp)		((scp)->fs_regs[AR5])
47 
48 #define INITIALIZE_UX_SIGNAL_CODES()					\
49 {									\
50   DECLARE_UX_SIGNAL_CODE						\
51     (SIGFPE, (~ 0L), 0, "software floating point exception");		\
52   DECLARE_UX_SIGNAL_CODE						\
53     (SIGFPE, (~ 0L), 5, "integer divide by zero");			\
54   DECLARE_UX_SIGNAL_CODE						\
55     (SIGFPE, (1L << 15), (1L << 15), "branch/set on unordered");	\
56   DECLARE_UX_SIGNAL_CODE						\
57     (SIGFPE, (1L << 14), (1L << 14), "signalling NAN");			\
58   DECLARE_UX_SIGNAL_CODE						\
59     (SIGFPE, (1L << 13), (1L << 13), "operand error");			\
60   DECLARE_UX_SIGNAL_CODE						\
61     (SIGFPE, (1L << 12), (1L << 12), "overflow");			\
62   DECLARE_UX_SIGNAL_CODE						\
63     (SIGFPE, (1L << 11), (1L << 11), "underflow");			\
64   DECLARE_UX_SIGNAL_CODE						\
65     (SIGFPE, (1L << 10), (1L << 10), "divide by zero");			\
66   DECLARE_UX_SIGNAL_CODE						\
67     (SIGFPE, (1L << 9), (1L << 9), "inexact operation");		\
68   DECLARE_UX_SIGNAL_CODE						\
69     (SIGFPE, (1L << 8), (1L << 8), "inexact decimal input");		\
70   DECLARE_UX_SIGNAL_CODE						\
71     (SIGILL, (~ 0L), 0, "illegal instruction");				\
72   DECLARE_UX_SIGNAL_CODE						\
73     (SIGILL, (~ 0L), 6, "check instruction");				\
74   DECLARE_UX_SIGNAL_CODE						\
75     (SIGILL, (~ 0L), 7, "TRAPV instruction");				\
76   DECLARE_UX_SIGNAL_CODE						\
77     (SIGILL, (~ 0L), 8, "privileged instruction");			\
78 }
79 
80 #endif /* hp9000s300 */
81 
82 #if defined(hp9000s800) || defined(__hp9000s800)
83 
84 /* The bottom 2 bits of the PC are protection bits.
85    They should be masked away before looking at the PC.
86  */
87 
88 #define PC_VALUE_MASK ((~0) << 2)
89 
90 /* pcoq is the offset (32 bit in 64 bit virtual address space)
91    in the space included in the corresponding sc_pcsq.
92    head is the current instruction, tail is the next instruction
93    which is not necessarily the following instruction because
94    of delayed branching, etc.
95    Both queues need to be collected for some screw cases of
96    debugging and if there is ever a hope to restart the code.
97  */
98 
99 #ifdef __HPUX__
100 
101 /* HPUX 9.x does not have siginfo, but HPUX 10.x does.  This can be
102    tested by the definition of SA_SIGINFO.  Since we want to support
103    both, we use the no-siginfo way.  */
104 
105 #ifdef SA_SIGINFO
106 #  undef SA_SIGINFO
107 #endif
108 
109 #include <sys/sysmacros.h>
110 
111 /* See <machine/save_state.h> included by <signal.h> */
112 #ifndef sc_pc
113 #  define sc_pc sc_pcoq_head
114 #endif
115 
116 #define ss_gr0 ss_flags		/* not really true */
117 
118 #define HAVE_SIGCONTEXT
119 #define SIGCONTEXT_ARG_T		struct sigcontext
120 #define SIGCONTEXT_NREGS		32
121 #define SIGCONTEXT_FIRST_REG(scp)	(&((scp)->sc_sl.sl_ss.ss_gr0))
122 #define SIGCONTEXT_SP(scp)		((scp) -> sc_sp)
123 #define SIGCONTEXT_PC(scp)		((scp) -> sc_pc)
124 #define SIGCONTEXT_RFREE(scp)		((scp)->sc_sl.sl_ss.ss_gr21)
125 #define SIGCONTEXT_SCHSP(scp)		((scp)->sc_sl.sl_ss.ss_gr22)
126 
127 # define INITIALIZE_UX_SIGNAL_CODES()					\
128 {									\
129   DECLARE_UX_SIGNAL_CODE						\
130     (SIGILL, (~ 0L), 8, "illegal instruction trap");			\
131   DECLARE_UX_SIGNAL_CODE						\
132     (SIGILL, (~ 0L), 9, "break instruction trap");			\
133   DECLARE_UX_SIGNAL_CODE						\
134     (SIGILL, (~ 0L), 10, "privileged operation trap");			\
135   DECLARE_UX_SIGNAL_CODE						\
136     (SIGILL, (~ 0L), 11, "privileged register trap");			\
137   DECLARE_UX_SIGNAL_CODE						\
138     (SIGFPE, (~ 0L), 12, "overflow trap");				\
139   DECLARE_UX_SIGNAL_CODE						\
140     (SIGFPE, (~ 0L), 13, "conditional trap");				\
141   DECLARE_UX_SIGNAL_CODE						\
142     (SIGFPE, (~ 0L), 14, "assist exception trap");			\
143   DECLARE_UX_SIGNAL_CODE						\
144     (SIGFPE, (~ 0L), 22, "assist emulation trap");			\
145 }
146 
147 # define SPECIAL_SIGNAL_CODE_NAMES()					\
148 {									\
149   if ((signo == SIGFPE) && (code == 14))				\
150     switch ((((*scp) . sc_sl . sl_ss . ss_frexcp1) >> 26) & 0x3f)	\
151       {									\
152       case 0x20:							\
153 	name = "invalid operation";					\
154 	break;								\
155       case 0x10:							\
156 	name = "divide by zero";					\
157 	break;								\
158       case 0x08:							\
159 	name = "overflow";						\
160 	break;								\
161       case 0x04:							\
162       case 0x14:							\
163       case 0x24:							\
164       case 0x34:							\
165 	name = "underflow";						\
166 	break;								\
167       case 0x02:							\
168 	name = "inexact";						\
169 	break;								\
170       case 0x0a:							\
171 	name = "inexact and overflow";					\
172 	break;								\
173       case 0x06:							\
174       case 0x16:							\
175       case 0x26:							\
176       case 0x36:							\
177 	name = "inexact and underflow";					\
178 	break;								\
179       }									\
180 }
181 
182 #else /* not __HPUX__, BSD ? */
183 
184 # ifndef sc_pc
185 #  define sc_pc				sc_pcoqh
186 # endif /* sc_pc */
187 
188 #endif /* __HPUX__ */
189 
190 #endif /* hp9000s800 */
191 
192 #ifdef sun3
193 
194 struct full_sigcontext
195 {
196   struct sigcontext * fs_original;
197   unsigned long fs_regs [SIGCONTEXT_NREGS];
198 };
199 
200 #define HAVE_SIGCONTEXT
201 #define SIGCONTEXT_ARG_T		struct sigcontext
202 #define SIGCONTEXT_T			struct full_sigcontext
203 #define SIGCONTEXT_NREGS		15 /* missing sp */
204 #define SIGCONTEXT_FIRST_REG(scp)	(& (((scp) -> fs_regs) [0]))
205 #define SIGCONTEXT_SP(scp)		((scp)->fs_original->sc_sp)
206 #define SIGCONTEXT_PC(scp)		((scp)->fs_original->sc_pc)
207 #define SIGCONTEXT_RFREE(scp)		(((scp) -> fs_regs) [8 + 5]) /* A5 */
208 
209 #define DECLARE_SIGCONTEXT(scp, arg)					\
210   SIGCONTEXT_T scp [1];							\
211   static void sun3_save_regs, (int *);					\
212   sun3_save_regs (& ((((scp) [0]) . fs_regs) [0]));			\
213   (((scp) [0]) . fs_original) = (arg)
214 
215 #endif /* sun3 */
216 
217 #ifdef vax
218 
219 struct full_sigcontext
220 {
221   struct sigcontext * fs_original;
222   int fs_regs [SIGCONTEXT_NREGS];
223 };
224 
225 #define HAVE_SIGCONTEXT
226 #define SIGCONTEXT_ARG_T		struct sigcontext
227 #define SIGCONTEXT_T			struct full_sigcontext
228 #define SIGCONTEXT_NREGS		16
229 #define SIGCONTEXT_FIRST_REG(scp)	(&((scp)->fs_regs[0]))
230 #define SIGCONTEXT_SP(scp)		((scp)->fs_original->sc_sp)
231 #define SIGCONTEXT_PC(scp)		((scp)->fs_original->sc_pc)
232 #define SIGCONTEXT_RFREE(scp)		((scp)->fs_regs[12]) /* fp */
233 
234 /* r0 has to be kludged. */
235 #define DECLARE_SIGCONTEXT(partial, full)				\
236   SIGCONTEXT_T scp [1];							\
237   static int vax_get_r0 (void);						\
238   static int * vax_save_start (int *, int);				\
239   static void vax_save_finish						\
240     (int *,								\
241 		       struct sigcontext *,				\
242 		       struct full_sigcontext *);			\
243   vax_save_finish ((vax_save_start ((& ((((full) [0]) . fs_regs) [0])),	\
244 				    (vax_get_r0 ()))),			\
245 		   (partial),						\
246 		   (&(full)[0]))
247 
248 #endif /* vax */
249 
250 #ifdef mips
251 #ifdef __IRIX__
252 
253 /* Information on sigcontext structure in signal.h */
254 
255 #define HAVE_SIGCONTEXT
256 #define SIGCONTEXT_ARG_T		struct sigcontext
257 #define SIGCONTEXT_NREGS		32
258 #define SIGCONTEXT_FIRST_REG(scp)	(& (((scp) -> sc_regs) [0]))
259 #define SIGCONTEXT_SP(scp)		(((scp) -> sc_regs) [29])
260 #define SIGCONTEXT_PC(scp)		((scp) -> sc_pc)
261 #define SIGCONTEXT_RFREE(scp)		(((scp) -> sc_regs) [9])
262 #define SIGCONTEXT_SCHSP(scp)		(((scp) -> sc_regs) [3])
263 
264 #define INITIALIZE_UX_SIGNAL_CODES()					\
265 {									\
266   DECLARE_UX_SIGNAL_CODE						\
267     (SIGTRAP, (~ 0L), BRK_OVERFLOW, "integer overflow trap");		\
268   DECLARE_UX_SIGNAL_CODE						\
269     (SIGTRAP, (~ 0L), BRK_DIVZERO, "integer divide by 0 trap");		\
270   DECLARE_UX_SIGNAL_CODE						\
271     (SIGTRAP, (~ 0L), BRK_MULOVF, "integer multiply overflow");		\
272   DECLARE_UX_SIGNAL_CODE						\
273     (SIGFPE,  (  0L),       0,      "floating-point exception");	\
274   DECLARE_UX_SIGNAL_CODE						\
275     (SIGSEGV, (~ 0L),       EFAULT,   "Invalid virtual address");	\
276   DECLARE_UX_SIGNAL_CODE						\
277     (SIGSEGV, (~ 0L),       EACCES,   "Read-only address");		\
278   DECLARE_UX_SIGNAL_CODE						\
279     (SIGSEGV, (~ 0L),       ENXIO,   "Read beyond mapped object");	\
280 }
281 
282 #else /* not __IRIX__ */
283 #ifndef _SYSV4
284 
285 #define HAVE_SIGCONTEXT
286 #define SIGCONTEXT_ARG_T		struct sigcontext
287 #define SIGCONTEXT_NREGS		32
288 #define SIGCONTEXT_FIRST_REG(scp)	(& (((scp) -> sc_regs) [0]))
289 #define SIGCONTEXT_SP(scp)		(((scp) -> sc_regs) [29])
290 #define SIGCONTEXT_PC(scp)		((scp) -> sc_pc)
291 #define SIGCONTEXT_RFREE(scp)		(((scp) -> sc_regs) [9])
292 #define SIGCONTEXT_SCHSP(scp)		(((scp) -> sc_regs) [3])
293 
294 #define INITIALIZE_UX_SIGNAL_CODES()					\
295 {									\
296   DECLARE_UX_SIGNAL_CODE						\
297     (SIGFPE, (~ 0L), FPE_INTOVF_TRAP, "integer overflow trap");		\
298   DECLARE_UX_SIGNAL_CODE						\
299     (SIGFPE, (~ 0L), FPE_INTDIV_TRAP, "integer divide by 0 trap");	\
300   DECLARE_UX_SIGNAL_CODE						\
301     (SIGFPE, (~ 0L), FPE_FLTOVF_TRAP, "floating-point overflow trap");	\
302   DECLARE_UX_SIGNAL_CODE						\
303     (SIGFPE, (~ 0L), FPE_FLTDIV_TRAP, "floating-point divide by 0 trap"); \
304   DECLARE_UX_SIGNAL_CODE						\
305     (SIGFPE, (~ 0L), FPE_FLTUND_TRAP, "floating-point underflow trap");	\
306   DECLARE_UX_SIGNAL_CODE						\
307     (SIGFPE, (~ 0L), FPE_DECOVF_TRAP, "decimal overflow trap");		\
308   DECLARE_UX_SIGNAL_CODE						\
309     (SIGFPE, (~ 0L), FPE_SUBRNG_TRAP, "subscript-range trap");		\
310   DECLARE_UX_SIGNAL_CODE						\
311     (SIGFPE, (~ 0L), FPE_FLTOVF_FAULT, "floating-point overflow fault"); \
312   DECLARE_UX_SIGNAL_CODE						\
313     (SIGFPE, (~ 0L), FPE_FLTDIV_FAULT, "floating-point divide by 0 fault"); \
314   DECLARE_UX_SIGNAL_CODE						\
315     (SIGFPE, (~ 0L), FPE_FLTUND_FAULT, "floating-point underflow fault"); \
316   DECLARE_UX_SIGNAL_CODE						\
317     (SIGILL, (~ 0L), ILL_PRIVIN_FAULT, "reserved instruction trap");	\
318   DECLARE_UX_SIGNAL_CODE						\
319     (SIGILL, (~ 0L), ILL_RESOP_FAULT, "reserved operand trap");		\
320   DECLARE_UX_SIGNAL_CODE						\
321     (SIGILL, (~ 0L), ILL_RESAD_FAULT, "reserved addressing trap");	\
322 }
323 
324 #else /* _SYSV4 */
325 
326 /* Many of these definitions are not specific to the MIPS processor. */
327 
328 #include <sys/siginfo.h>
329 #include <sys/ucontext.h>
330 
331 /* For Sony NEWS-OS 5.0.1 and earlier: */
332 #if defined(sonyrisc) && !defined(_CFE)
333 #  define gregs gpregs
334 #endif
335 
336 #define SIGINFO_T siginfo_t *
337 #define SIGINFO_VALID_P(info) ((info) != 0)
338 #define SIGINFO_CODE(info) ((info) -> si_code)
339 
340 #define __SIGCONTEXT_REG(scp, ir) ((((scp) -> uc_mcontext) . gregs) [(ir)])
341 
342 #define HAVE_SIGCONTEXT
343 #define SIGCONTEXT_ARG_T void
344 #define SIGCONTEXT_T ucontext_t
345 #define SIGCONTEXT_NREGS NGREG
346 #define SIGCONTEXT_FIRST_REG(scp) (& (__SIGCONTEXT_REG (scp, 0)))
347 #define SIGCONTEXT_SP(scp) (__SIGCONTEXT_REG (scp, CXT_SP))
348 #define SIGCONTEXT_PC(scp) (__SIGCONTEXT_REG (scp, CXT_EPC))
349 #define SIGCONTEXT_RFREE(scp) (__SIGCONTEXT_REG (scp, CXT_T1))
350 #define SIGCONTEXT_SCHSP(scp) (__SIGCONTEXT_REG (scp, CXT_V1))
351 
352 #define INITIALIZE_UX_SIGNAL_CODES()					\
353 {									\
354   DECLARE_UX_SIGNAL_CODE						\
355     (SIGFPE, (~ 0L), FPE_INTDIV, "integer divide by 0 trap");		\
356   DECLARE_UX_SIGNAL_CODE						\
357     (SIGFPE, (~ 0L), FPE_INTOVF, "integer overflow trap");		\
358   DECLARE_UX_SIGNAL_CODE						\
359     (SIGFPE, (~ 0L), FPE_FLTDIV, "floating-point divide by 0 trap");	\
360   DECLARE_UX_SIGNAL_CODE						\
361     (SIGFPE, (~ 0L), FPE_FLTOVF, "floating-point overflow trap");	\
362   DECLARE_UX_SIGNAL_CODE						\
363     (SIGFPE, (~ 0L), FPE_FLTUND, "floating-point underflow trap");	\
364   DECLARE_UX_SIGNAL_CODE						\
365     (SIGFPE, (~ 0L), FPE_FLTRES, "floating-point inexact result");	\
366   DECLARE_UX_SIGNAL_CODE						\
367     (SIGFPE, (~ 0L), FPE_FLTSUB, "subscript-range trap");		\
368   DECLARE_UX_SIGNAL_CODE						\
369     (SIGFPE, (~ 0L), FPE_FLTINV, "invalid floating-point operation");	\
370   DECLARE_UX_SIGNAL_CODE						\
371     (SIGILL, (~ 0L), ILL_ILLOPC, "illegal opcode trap");		\
372   DECLARE_UX_SIGNAL_CODE						\
373     (SIGILL, (~ 0L), ILL_ILLOPN, "illegal operand trap");		\
374   DECLARE_UX_SIGNAL_CODE						\
375     (SIGILL, (~ 0L), ILL_ILLADR, "illegal addressing mode trap");	\
376   DECLARE_UX_SIGNAL_CODE						\
377     (SIGILL, (~ 0L), ILL_ILLTRP, "illegal trap");			\
378   DECLARE_UX_SIGNAL_CODE						\
379     (SIGILL, (~ 0L), ILL_PRVOPC, "privileged opcode trap");		\
380   DECLARE_UX_SIGNAL_CODE						\
381     (SIGILL, (~ 0L), ILL_PRVREG, "privileged register trap");		\
382   DECLARE_UX_SIGNAL_CODE						\
383     (SIGILL, (~ 0L), ILL_COPROC, "co-processor trap");			\
384   DECLARE_UX_SIGNAL_CODE						\
385     (SIGILL, (~ 0L), ILL_BADSTK, "bad stack trap");			\
386 }
387 
388 #endif /* _SYSV4 */
389 #endif /* __IRIX__ */
390 #endif /* mips */
391 
392 #ifdef __IA32__
393 
394 #if defined(__FreeBSD__) || defined(__DragonFly__)
395 #  include <ucontext.h>
396 #endif
397 
398 #ifdef _MACH_UNIX
399 /* The following are true for Mach (BSD 4.3 compatible).
400    I don't know about SCO or other versions.  */
401 
402 #define HAVE_SIGCONTEXT
403 #define SIGCONTEXT_ARG_T		struct sigcontext
404 #define SIGCONTEXT_NREGS		8
405 #define SIGCONTEXT_FIRST_REG(scp)	(& ((scp) -> sc_edi))
406 #define SIGCONTEXT_SP(scp)		((scp) -> sc_esp)
407 #define SIGCONTEXT_PC(scp)		((scp) -> sc_eip)
408 #define SIGCONTEXT_RFREE(scp)		((scp) -> sc_edi)
409 
410 /* INITIALIZE_UX_SIGNAL_CODES should be defined. */
411 
412 #endif /* _MACH_UNIX */
413 
414 #endif /* __IA32__ */
415 
416 #ifdef __x86_64__
417 
418 #if defined(__FreeBSD__)
419 #  include <ucontext.h>
420 #endif
421 
422 #endif /* __x86_64__ */
423 
424 #ifdef __alpha
425 
426 #define HAVE_SIGCONTEXT
427 #define SIGCONTEXT_ARG_T		struct sigcontext
428 #define SIGCONTEXT_NREGS		32
429 #define SIGCONTEXT_FIRST_REG(scp)	(& (((scp) -> sc_regs) [0]))
430 #define SIGCONTEXT_SP(scp)		(((scp) -> sc_regs) [30])
431 #define SIGCONTEXT_PC(scp)		((scp) -> sc_pc)
432 #define SIGCONTEXT_RFREE(scp)		(((scp) -> sc_regs) [4])
433 #define SIGCONTEXT_SCHSP(scp)		(((scp) -> sc_regs) [2])
434 
435 #ifdef FPE_COMPLETE_FAULT
436 #define STUPID_FIRST_SIGNAL()						\
437   DECLARE_UX_SIGNAL_CODE						\
438     (SIGFPE, (~ 0L), FPE_COMPLETE_FAULT, "software completion fault")
439 #endif
440 
441 #ifdef FPE_UNIMP_FAULT
442 #define STUPID_FIRST_SIGNAL()						\
443   DECLARE_UX_SIGNAL_CODE						\
444     (SIGFPE, (~ 0L), FPE_UNIMP_FAULT, "unimplemented fp instruction fault")
445 #endif
446 
447 #ifndef STUPID_FIRST_SIGNAL
448 #define STUPID_FIRST_SIGNAL()	{ }
449 #endif
450 
451 #define INITIALIZE_UX_SIGNAL_CODES()					\
452 {                                                                       \
453   STUPID_FIRST_SIGNAL();						\
454   DECLARE_UX_SIGNAL_CODE						\
455     (SIGFPE, (~ 0L), FPE_INVALID_FAULT, "invalid operation fault");	\
456   DECLARE_UX_SIGNAL_CODE						\
457     (SIGFPE, (~ 0L), FPE_INEXACT_FAULT, "floating-point inexact result");\
458   DECLARE_UX_SIGNAL_CODE						\
459     (SIGFPE, (~ 0L), FPE_INTOVF_FAULT, "integer overflow fault");	\
460 }
461 
462 #endif /* __alpha */
463 
464 #ifdef __sparc
465 
466 #ifdef __svr4__
467 /* SPARC Solaris */
468 
469 /* This is adapted from the MIPS SysV4 code above,
470    adjusted for the SPARC. */
471 
472 #include <siginfo.h>
473 #include <ucontext.h>
474 
475 #define __SIGCONTEXT_REG(scp, ir) ((((scp) -> uc_mcontext) . gregs) [(ir)])
476 
477 /* SIGINFO_T, SIGINFO_VALID_P, SIGINFO_CODE, SIGINFO_ARG_T, and SIGCONTEXT_T
478    are all defined by the conditional for _POSIX_REALTIME_SIGNALS below. */
479 
480 #define HAVE_SIGCONTEXT
481 #define SIGCONTEXT_NREGS NGREG
482 #define SIGCONTEXT_FIRST_REG(scp) (& (__SIGCONTEXT_REG (scp, 0)))
483 
484 #define SIGCONTEXT_SP(scp) (__SIGCONTEXT_REG (scp, REG_SP))
485 #define SIGCONTEXT_PC(scp) (__SIGCONTEXT_REG (scp, REG_PC))
486 
487 /* I don't think that either of these actually matters for liarc, which
488    is all that we support on the SPARC at the moment. */
489 
490 #define SIGCONTEXT_RFREE(scp) 0
491 #define SIGCONTEXT_SCHSP(scp) 0
492 
493 #define INITIALIZE_UX_SIGNAL_CODES()					\
494 {									\
495   DECLARE_UX_SIGNAL_CODE						\
496     (SIGFPE, (~ 0L), FPE_INTDIV, "integer divide by 0 trap");		\
497   DECLARE_UX_SIGNAL_CODE						\
498     (SIGFPE, (~ 0L), FPE_INTOVF, "integer overflow trap");		\
499   DECLARE_UX_SIGNAL_CODE						\
500     (SIGFPE, (~ 0L), FPE_FLTDIV, "floating-point divide by 0 trap");	\
501   DECLARE_UX_SIGNAL_CODE						\
502     (SIGFPE, (~ 0L), FPE_FLTOVF, "floating-point overflow trap");	\
503   DECLARE_UX_SIGNAL_CODE						\
504     (SIGFPE, (~ 0L), FPE_FLTUND, "floating-point underflow trap");	\
505   DECLARE_UX_SIGNAL_CODE						\
506     (SIGFPE, (~ 0L), FPE_FLTRES, "floating-point inexact result");	\
507   DECLARE_UX_SIGNAL_CODE						\
508     (SIGFPE, (~ 0L), FPE_FLTSUB, "subscript-range trap");		\
509   DECLARE_UX_SIGNAL_CODE						\
510     (SIGFPE, (~ 0L), FPE_FLTINV, "invalid floating-point operation");	\
511   DECLARE_UX_SIGNAL_CODE						\
512     (SIGILL, (~ 0L), ILL_ILLOPC, "illegal opcode trap");		\
513   DECLARE_UX_SIGNAL_CODE						\
514     (SIGILL, (~ 0L), ILL_ILLOPN, "illegal operand trap");		\
515   DECLARE_UX_SIGNAL_CODE						\
516     (SIGILL, (~ 0L), ILL_ILLADR, "illegal addressing mode trap");	\
517   DECLARE_UX_SIGNAL_CODE						\
518     (SIGILL, (~ 0L), ILL_ILLTRP, "illegal trap");			\
519   DECLARE_UX_SIGNAL_CODE						\
520     (SIGILL, (~ 0L), ILL_PRVOPC, "privileged opcode trap");		\
521   DECLARE_UX_SIGNAL_CODE						\
522     (SIGILL, (~ 0L), ILL_PRVREG, "privileged register trap");		\
523   DECLARE_UX_SIGNAL_CODE						\
524     (SIGILL, (~ 0L), ILL_COPROC, "co-processor trap");			\
525   DECLARE_UX_SIGNAL_CODE						\
526     (SIGILL, (~ 0L), ILL_BADSTK, "bad stack trap");			\
527 }
528 
529 /* Solaris's siginfo(3HEAD) man page lists many more signal codes, but
530    so does Linux's sigaction(2) man page, and this is the same list as
531    in the Linux section.  Unless this is used for anything other than
532    documentative purposes during trap recovery, then I can't imagine
533    why these lists aren't populated more completely. */
534 
535 #endif /* __svr4__ */
536 
537 #endif /* __sparc */
538 
539 #ifdef __linux__
540 
541 #  include <ucontext.h>
542 
543 /* This isn't really the right test: what we really want to know is if
544    the kernel supports the newer signal-delivery mechanism.  */
545 
546 #  ifdef _POSIX_REALTIME_SIGNALS
547 
548 #  ifdef __IA32__
549 #    define __SIGCONTEXT_REG(scp, ir) ((((scp) -> uc_mcontext) . gregs) [(ir)])
550 #    define HAVE_SIGCONTEXT
551 #    define SIGCONTEXT_NREGS NGREG
552 #    define SIGCONTEXT_FIRST_REG(scp) (& (__SIGCONTEXT_REG (scp, REG_GS)))
553 #    define SIGCONTEXT_SP(scp) (__SIGCONTEXT_REG (scp, REG_ESP))
554 #    define SIGCONTEXT_PC(scp) (__SIGCONTEXT_REG (scp, REG_EIP))
555 #    define SIGCONTEXT_RFREE(scp) (__SIGCONTEXT_REG (scp, REG_EDI))
556 #  endif /* __IA32__ */
557 
558 #  ifdef __x86_64__
559 #    define __SIGCONTEXT_REG(scp, ir) ((((scp) -> uc_mcontext) . gregs) [(ir)])
560 #    define HAVE_SIGCONTEXT
561 #    define SIGCONTEXT_NREGS NGREG
562 #    define SIGCONTEXT_FIRST_REG(scp) (& (__SIGCONTEXT_REG (scp, REG_R8)))
563 #    define SIGCONTEXT_SP(scp) (__SIGCONTEXT_REG (scp, REG_RSP))
564 #    define SIGCONTEXT_PC(scp) (__SIGCONTEXT_REG (scp, REG_RIP))
565 #    define SIGCONTEXT_RFREE(scp) (__SIGCONTEXT_REG (scp, REG_RDI))
566 #  endif /* __x86_64__ */
567 
568 #  else /* not _POSIX_REALTIME_SIGNALS */
569 
570 #    ifdef __IA32__
571 
572 /* In Linux 2.0 and earlier, signal handlers are called with one
573    argument.  There's an "iBCS2 signal stack" register dump just above
574    it.  Thus, the fictitious `info' argument to the handler is
575    actually the first member of this register dump (described by
576    linux_sigcontext_t, below).  Unfortunately, kludging SIGINFO_CODE
577    to access the sc_trapno will fail later on when looking at the
578    saved_info.  */
579 
580 typedef struct
581 {
582   unsigned short gs, __gsh;
583   unsigned short fs, __fsh;
584   unsigned short es, __esh;
585   unsigned short ds, __dsh;
586   unsigned long edi;
587   unsigned long esi;
588   unsigned long ebp;
589   unsigned long esp;
590   unsigned long ebx;
591   unsigned long edx;
592   unsigned long ecx;
593   unsigned long eax;
594   unsigned long trapno;
595   unsigned long err;
596   unsigned long eip;
597   unsigned short cs, __csh;
598   unsigned long eflags;
599   unsigned long esp_at_signal;
600   unsigned short ss, __ssh;
601   void * fpstate;
602 } linux_sigcontext_t;
603 
604 #      define HAVE_SIGCONTEXT
605 #      define SIGCONTEXT_T linux_sigcontext_t
606 #      define SIGCONTEXT_NREGS 19
607 #      define SIGCONTEXT_FIRST_REG(scp) (scp)
608 #      define SIGCONTEXT_SP(scp) ((scp) -> esp)
609 #      define SIGCONTEXT_PC(scp) ((scp) -> eip)
610 #      define SIGCONTEXT_RFREE(scp) ((scp) -> edi)
611 
612 /* DECLARE_SIGCONTEXT gives us a chance to generate a pointer to the
613    register dump, since it is used at the beginning of STD_HANDLER's.
614    In terms of the expected arguments to the STD_ signal HANDLER's,
615    the register dump is right above `signo', at `info', one long below
616    `pscp', which is what DECLARE_SIGCONTEXT is getting for `arg'.
617    Thus, our pointer to a scp is initialized to the address of `arg'
618    minus 1 long.  */
619 
620 #      define DECLARE_SIGCONTEXT(scp, arg)				\
621   SIGCONTEXT_T * scp ATTRIBUTE((unused));				\
622   scp = ((SIGCONTEXT_T *) (((unsigned long *) (& (arg))) - 1))
623 
624 #    endif /* __IA32__ */
625 
626 #  endif /* _POSIX_REALTIME_SIGNALS */
627 
628 #  define INITIALIZE_UX_SIGNAL_CODES()					\
629 {									\
630   DECLARE_UX_SIGNAL_CODE						\
631     (SIGFPE, (~ 0L), FPE_INTDIV, "integer divide by 0 trap");		\
632   DECLARE_UX_SIGNAL_CODE						\
633     (SIGFPE, (~ 0L), FPE_INTOVF, "integer overflow trap");		\
634   DECLARE_UX_SIGNAL_CODE						\
635     (SIGFPE, (~ 0L), FPE_FLTDIV, "floating-point divide by 0 trap");	\
636   DECLARE_UX_SIGNAL_CODE						\
637     (SIGFPE, (~ 0L), FPE_FLTOVF, "floating-point overflow trap");	\
638   DECLARE_UX_SIGNAL_CODE						\
639     (SIGFPE, (~ 0L), FPE_FLTUND, "floating-point underflow trap");	\
640   DECLARE_UX_SIGNAL_CODE						\
641     (SIGFPE, (~ 0L), FPE_FLTRES, "floating-point inexact result");	\
642   DECLARE_UX_SIGNAL_CODE						\
643     (SIGFPE, (~ 0L), FPE_FLTSUB, "subscript-range trap");		\
644   DECLARE_UX_SIGNAL_CODE						\
645     (SIGFPE, (~ 0L), FPE_FLTINV, "invalid floating-point operation");	\
646   DECLARE_UX_SIGNAL_CODE						\
647     (SIGILL, (~ 0L), ILL_ILLOPC, "illegal opcode trap");		\
648   DECLARE_UX_SIGNAL_CODE						\
649     (SIGILL, (~ 0L), ILL_ILLOPN, "illegal operand trap");		\
650   DECLARE_UX_SIGNAL_CODE						\
651     (SIGILL, (~ 0L), ILL_ILLADR, "illegal addressing mode trap");	\
652   DECLARE_UX_SIGNAL_CODE						\
653     (SIGILL, (~ 0L), ILL_ILLTRP, "illegal trap");			\
654   DECLARE_UX_SIGNAL_CODE						\
655     (SIGILL, (~ 0L), ILL_PRVOPC, "privileged opcode trap");		\
656   DECLARE_UX_SIGNAL_CODE						\
657     (SIGILL, (~ 0L), ILL_PRVREG, "privileged register trap");		\
658   DECLARE_UX_SIGNAL_CODE						\
659     (SIGILL, (~ 0L), ILL_COPROC, "co-processor trap");			\
660   DECLARE_UX_SIGNAL_CODE						\
661     (SIGILL, (~ 0L), ILL_BADSTK, "bad stack trap");			\
662   DECLARE_UX_SIGNAL_CODE						\
663     (SIGSEGV, (~ 0L), SEGV_MAPERR, "address not mapped to object");	\
664   DECLARE_UX_SIGNAL_CODE						\
665     (SIGSEGV, (~ 0L), SEGV_ACCERR, "invalid permissions for mapped object"); \
666   DECLARE_UX_SIGNAL_CODE						\
667     (SIGBUS, (~ 0L), BUS_ADRALN, "invalid address alignment");		\
668   DECLARE_UX_SIGNAL_CODE						\
669     (SIGBUS, (~ 0L), BUS_ADRERR, "nonexistent physical address");	\
670   DECLARE_UX_SIGNAL_CODE						\
671     (SIGBUS, (~ 0L), BUS_OBJERR, "object-specific hardware error");	\
672   DECLARE_UX_SIGNAL_CODE						\
673     (SIGTRAP, (~ 0L), TRAP_BRKPT, "process breakpoint");		\
674   DECLARE_UX_SIGNAL_CODE						\
675     (SIGTRAP, (~ 0L), TRAP_TRACE, "process trace trap");		\
676 }
677 
678 #endif /* __linux__ */
679 
680 /* Judging by the CVS logs, NetBSD seems to have begun supporting
681    siginfo cruft somewhere around 1.5ish or 1.6ish, so 2.0 is a
682    reasonable guess.  */
683 
684 #if defined(__NetBSD__)
685 #include <sys/param.h>
686 #if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 200000000
687 
688 #  define HAVE_SIGACTION_SIGINFO_SIGNALS
689 
690 #  include <sys/siginfo.h>
691 #  include <sys/ucontext.h>
692 #  include <machine/mcontext.h>
693 
694 #  ifdef __IA32__
695 #    define SIGCONTEXT_RFREE(scp) ((SIGCONTEXT_FIRST_REG (scp)) [_REG_EDI])
696 #    define HAVE_NETBSD_GENERIC_MCONTEXT
697 #  endif
698 
699 #  ifdef __x86_64__
700 #    define SIGCONTEXT_RFREE(scp) ((SIGCONTEXT_FIRST_REG (scp)) [_REG_RDI])
701 #    define HAVE_NETBSD_GENERIC_MCONTEXT
702 #  endif
703 
704 /* When I checked, on 2010-07-22, the only NetBSD ports without the
705    generic mcontext interface were IA-64 and usermode.  */
706 
707 #  ifdef HAVE_NETBSD_GENERIC_MCONTEXT
708 #    define HAVE_SIGCONTEXT
709 #    define SIGCONTEXT_NREGS _NGREG
710 #    define SIGCONTEXT_FIRST_REG(scp) (((scp) -> uc_mcontext) . __gregs)
711 #    define SIGCONTEXT_SP(scp) (_UC_MACHINE_SP (scp))
712 #    define SIGCONTEXT_PC(scp) (_UC_MACHINE_PC (scp))
713 #  endif
714 
715 #  define INITIALIZE_UX_SIGNAL_CODES()                                  \
716   do {                                                                  \
717     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_ILLOPC, "Illegal opcode"); \
718     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_ILLOPN, "Illegal operand"); \
719     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_ILLADR, "Illegal addressing mode"); \
720     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_ILLTRP, "Illegal trap"); \
721     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_PRVOPC, "Privileged opcode"); \
722     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_PRVREG, "Privileged register"); \
723     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_COPROC, "Coprocessor error"); \
724     DECLARE_UX_SIGNAL_CODE (SIGILL, (~0L), ILL_BADSTK, "Internal stack error"); \
725     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_INTDIV, "Integer divide by zero"); \
726     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_INTOVF, "Integer overflow"); \
727     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTDIV, "Floating-point divide by zero"); \
728     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTOVF, "Floating-point overflow"); \
729     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTUND, "Floating-point underflow"); \
730     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTRES, "Floating-point inexact result"); \
731     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTINV, "Invalid floating-point operation"); \
732     DECLARE_UX_SIGNAL_CODE (SIGFPE, (~0L), FPE_FLTSUB, "Subscript out of range"); \
733     DECLARE_UX_SIGNAL_CODE (SIGSEGV, (~0L), SEGV_MAPERR, "Address not mapped to object"); \
734     DECLARE_UX_SIGNAL_CODE (SIGSEGV, (~0L), SEGV_ACCERR, "Invalid permissions for mapped object"); \
735     DECLARE_UX_SIGNAL_CODE (SIGBUS, (~0L), BUS_ADRALN, "Invalid address alignment"); \
736     DECLARE_UX_SIGNAL_CODE (SIGBUS, (~0L), BUS_ADRERR, "Nonexistent physical address"); \
737     DECLARE_UX_SIGNAL_CODE (SIGBUS, (~0L), BUS_OBJERR, "Object-specific hardware error"); \
738     DECLARE_UX_SIGNAL_CODE (SIGTRAP, (~0L), TRAP_BRKPT, "Process breakpoint"); \
739     DECLARE_UX_SIGNAL_CODE (SIGTRAP, (~0L), TRAP_TRACE, "Process trace trap"); \
740   } while (0)
741 
742 #endif /* __NetBSD_Version__ >= 200000000 */
743 #endif /* __NetBSD__ */
744 
745 #ifdef _POSIX_REALTIME_SIGNALS
746 #  define HAVE_SIGACTION_SIGINFO_SIGNALS
747 #endif
748 
749 #ifdef HAVE_SIGACTION_SIGINFO_SIGNALS
750 #  define SIGINFO_T siginfo_t *
751 #  define SIGINFO_VALID_P(info) (1)
752 #  define SIGINFO_CODE(info) ((info) -> si_code)
753 #  define SIGCONTEXT_ARG_T void
754 #  define SIGCONTEXT_T ucontext_t
755 #endif
756 
757 #ifndef SIGINFO_T
758 #  define SIGINFO_T int
759 #  define SIGINFO_VALID_P(info) (0)
760 #  define SIGINFO_CODE(info) (0)
761 #endif
762 
763 #ifndef SIGCONTEXT_ARG_T
764 #  define SIGCONTEXT_ARG_T int
765 #endif
766 
767 #ifndef SIGCONTEXT_T
768 #  define SIGCONTEXT_T SIGCONTEXT_ARG_T
769 #endif
770 
771 #ifndef DECLARE_SIGCONTEXT
772 #  define DECLARE_SIGCONTEXT(scp, arg)					\
773      SIGCONTEXT_T * scp ATTRIBUTE ((unused));				\
774      scp = ((SIGCONTEXT_T *) (arg))
775 #endif
776 
777 #ifndef SIGCONTEXT_NREGS
778 #  define SIGCONTEXT_NREGS (0)
779 #endif
780 
781 #ifndef SIGCONTEXT_FIRST_REG
782 #  define SIGCONTEXT_FIRST_REG(scp) (0)
783 #endif
784 
785 #ifndef SIGCONTEXT_SP
786 #  define SIGCONTEXT_SP(scp) (0)
787 #endif
788 
789 #ifndef SIGCONTEXT_PC
790 #  define SIGCONTEXT_PC(scp) (0)
791 #endif
792 
793 #ifndef SIGCONTEXT_RFREE
794 #  define SIGCONTEXT_RFREE(scp) ((unsigned long) heap_alloc_limit)
795 #endif
796 
797 #ifndef SIGCONTEXT_SCHSP
798 #  define SIGCONTEXT_SCHSP SIGCONTEXT_SP
799 #endif
800 
801 #ifndef INITIALIZE_UX_SIGNAL_CODES
802 #  define INITIALIZE_UX_SIGNAL_CODES()
803 #endif
804 
805 #ifdef _AIX
806    extern int _etext;
807 #endif
808 
809 #if defined(__linux__) || defined(__NetBSD__)
810    extern unsigned int _init;
811    extern unsigned int etext;
812 #  define ADDRESS_UCODE_P(addr)						\
813      ((((unsigned int *) (addr)) >= (&_init))				\
814       && (((unsigned int *) (addr)) <= (&etext)))
815 #endif
816 
817 #ifdef __CYGWIN__
818    extern unsigned int end;
819 #endif
820 
821 #ifndef ADDRESS_UCODE_P
822 #  define ADDRESS_UCODE_P(addr) (0)
823 #endif
824 
825 /* Machine/OS-independent section */
826 
827 enum trap_state
828 {
829   trap_state_trapped,
830   trap_state_exit,
831   trap_state_suspend,
832   trap_state_query,
833   trap_state_recover,
834   trap_state_exitting_soft,
835   trap_state_exitting_hard
836 };
837 
838 extern void UX_initialize_trap_recovery (void);
839 extern enum trap_state OS_set_trap_state (enum trap_state state);
840 extern void hard_reset (SIGCONTEXT_T * scp);
841 extern void soft_reset (void);
842 extern void trap_handler
843   (const char *, int, SIGINFO_T, SIGCONTEXT_T *);
844 #ifdef CC_SUPPORT_P
845    extern SCHEME_OBJECT find_ccblock (unsigned long);
846 #endif
847 
848 #define STATE_UNKNOWN		(LONG_TO_UNSIGNED_FIXNUM (0))
849 #define STATE_PRIMITIVE		(LONG_TO_UNSIGNED_FIXNUM (1))
850 #define STATE_COMPILED_CODE	(LONG_TO_UNSIGNED_FIXNUM (2))
851 #define STATE_PROBABLY_COMPILED	(LONG_TO_UNSIGNED_FIXNUM (3))
852 #define STATE_BUILTIN		(LONG_TO_UNSIGNED_FIXNUM (4))
853 #define STATE_UTILITY		(LONG_TO_UNSIGNED_FIXNUM (5))  /* CommGas? */
854 
855 struct trap_recovery_info
856 {
857   SCHEME_OBJECT state;
858   SCHEME_OBJECT pc_info_1;
859   SCHEME_OBJECT pc_info_2;
860   SCHEME_OBJECT extra_trap_info;
861 };
862 
863 #endif /* SCM_UXTRAP_H */
864