source: trunk/ccl/lisp-kernel/lisp-exceptions.h @ 173

Last change on this file since 173 was 173, checked in by gb, 16 years ago

According to my calculations, you need 5 bits to express a 5-bit register
field (RT, RA, RB, etc.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.7 KB
Line 
1/*
2   Copyright (C) 1994-2001 Digitool, Inc
3   This file is part of OpenMCL. 
4
5   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
6   License , known as the LLGPL and distributed with OpenMCL as the
7   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
8   which is distributed with OpenMCL as the file "LGPL".  Where these
9   conflict, the preamble takes precedence. 
10
11   OpenMCL is referenced in the preamble as the "LIBRARY."
12
13   The LLGPL is also available online at
14   http://opensource.franz.com/preamble.html
15*/
16
17#ifndef __LISP_EXCEPTIONS_H__
18#define __LISP_EXCEPTIONS_H__ 1
19
20
21#include <stdlib.h>
22#include "memprotect.h"
23#include "gc.h"
24
25typedef enum {
26  kDebugger,
27  kContinue,
28  kExit
29} ErrAction;
30
31
32
33void
34zero_page(BytePtr);
35
36void
37zero_heap_segment(BytePtr);
38
39extern protected_area_ptr AllProtectedAreas;
40
41protected_area_ptr find_protected_area(BytePtr);
42
43OSStatus
44lisp_Debugger(ExceptionInformationPowerPC *, int, char *, ...);
45
46OSStatus
47handle_protection_violation(ExceptionInformationPowerPC *, siginfo_t *);
48
49protected_area_ptr
50new_protected_area(BytePtr, BytePtr, lisp_protection_kind, unsigned, Boolean);
51
52void
53unprotect_area_prefix(protected_area_ptr, size_t);
54
55void
56protect_area_prefix(protected_area_ptr, size_t);
57
58void
59protect_area(protected_area_ptr);
60
61
62void
63resize_dynamic_heap(BytePtr, unsigned);
64
65OSStatus
66PMCL_exception_handler(int, ExceptionInformationPowerPC *, TCR *, siginfo_t *);
67
68ErrAction
69error_action( void );
70
71void
72install_pmcl_exception_handlers();
73
74void
75unprotect_all_areas(void);
76
77void
78exception_cleanup(void);
79
80void
81exception_init();
82
83#define UUO_MASK 0xfc00000f
84#define IS_UUO(i) (((i) & UUO_MASK) == 0xb)
85/* If an instruction is a UUO, the minor opcode is in bits 21:27 */
86#define UUO_MINOR(u) (((u) >> 4) & 0x7f)
87
88
89typedef unsigned opcode, *pc;
90
91#ifdef LINUX
92/*
93  Different (recent) versions of glibc disagree about how
94  a ucontext is laid out (and about what an mcontext is.)
95  There's something like a pointer to a pt_regs structure
96  in the 12th word in both cases.  (Yes, this is an extremely
97  ugly hack; it would be better to conditionalize on the values
98  of GLIBC_VERSION/GLIBC_MINOR , but the discrepancy exists
99  in various flavors of glibc 2.3.)
100*/
101#define XP_PTREGS(x) (((struct pt_regs **)(x))[12])
102#define xpGPRvector(x) (XP_PTREGS(x)->gpr)
103#define xpGPR(x,gprno) (xpGPRvector(x)[gprno])
104#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (UInt32)(new)
105#define xpPC(x) (*((pc*)(&(XP_PTREGS(x)->nip))))
106#define set_xpPC(x,new) (xpPC(x) = (pc)(new))
107#define xpLR(x) (*((pc*)(&(XP_PTREGS(x)->link))))
108#define xpCTR(x) (*(pc*)(&(XP_PTREGS(x)->ctr)))
109#define xpXER(x) (XP_PTREGS(x)->xer)
110#define xpCCR(x) (XP_PTREGS(x)->ccr)
111#define xpMSR(x) (XP_PTREGS(x)->msr)
112#define xpDSISR(x) (XP_PTREGS(x)->dsisr)
113#define xpDAR(x) (XP_PTREGS(x)->dar)
114#define xpTRAP(x) (XP_PTREGS(x)->trap)
115#define xpFPSCR(x) (XP_PTREGS(x)->gpr[PT_FPSCR])
116#define xpFPRvector(x) ((double *)(&(XP_PTREGS(x)->gpr[PT_FPR0])))
117#define xpFPR(x,fprno) (xpFPRvector(x)[fprno])
118/*
119   Work around a Darwin G5 bug (present in OSX 10.2.7, 10.2.8, and later
120   versions.  See below for details.
121*/
122#define DarwinSigReturn(context)
123#endif
124
125#ifdef DARWIN
126#define xpGPRvector(x) (&(x->uc_mcontext->ss.r0))
127#define xpGPR(x,gprno) ((xpGPRvector(x))[gprno])
128#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (UInt32)(new)
129#define xpPC(x) (*((pc*) &(x->uc_mcontext->ss.srr0)))
130#define set_xpPC(x,new) (xpPC(x) = (pc)(new))
131#define xpLR(x) (*((pc*)(&(x->uc_mcontext->ss.lr))))
132#define xpCTR(x) (*(pc*)(&(x->uc_mcontext->ss.ctr)))
133#define xpXER(x) (x->uc_mcontext->ss.xer)
134#define xpCCR(x) (x->uc_mcontext->ss.cr)
135#define xpMSR(x) (x->uc_mcontext->ss.srr1)
136#define xpDSISR(x) (x->uc_mcontext->es.dsisr)
137#define xpDAR(x) (x->uc_mcontext->es.dar)
138#define xpTRAP(x) (x->uc_mcontext->es.exception)
139#define xpFPSCR(x) (x->uc_mcontext->fs.fpscr)
140#define xpFPRvector(x) (x->uc_mcontext->fs.fpregs)
141#define xpFPR(x,fprno) (xpFPRvector(x)[fprno])
142/* There's a bug in some versions of Darwin on G5 processors: FP context
143   isn't restored correctly on exit from a signal handler if the integer
144   context appears to be unmodified (the 64-bit context isn't set up
145   correctly by the kernel: only the first N bytes are copied out of
146   the kernel, where N = size of 32-bit context.
147*/
148#define DarwinSigReturn(x) syscall(103,x)
149#endif
150
151OSStatus
152handle_uuo(ExceptionInformationPowerPC *, opcode, pc);
153
154
155/*
156  Unconditional traps (tw, twi instructions) are used by the
157  operating system.  We use conditional traps.
158  */
159
160int
161is_conditional_trap(opcode);
162
163#define kNameBufLen 256
164#define TRAP_LOOKUP_TRIES 5   /* # instrs to scan before trap instr */
165
166void
167callback_for_trap (LispObj, ExceptionInformationPowerPC *, unsigned, unsigned, unsigned, unsigned);
168
169unsigned
170register_codevector_contains_pc (unsigned, unsigned);
171
172void
173callback_to_lisp (LispObj, ExceptionInformationPowerPC *, unsigned, unsigned, unsigned, unsigned, unsigned);
174
175OSStatus
176handle_trap(ExceptionInformationPowerPC *, opcode, pc);
177
178unsigned
179scan_for_instr( unsigned, unsigned, pc );
180
181size_t
182exception_fn_name( ExceptionInformationPowerPC *, int, char *, size_t );
183
184size_t
185symbol_name( unsigned, char *, size_t );
186
187void
188non_fatal_error( char * );
189
190
191#define UUO_INTERR (11)
192#define UUO_INTCERR (12)
193#define UUO_INTERR2 (13)
194#define UUO_INTCERR2 (14)
195
196#define UUO_FPUX_BINOP (22)
197#define UUO_ZERO_FPSCR (25)
198
199OSStatus
200box_signed_integer(ExceptionInformationPowerPC *, unsigned, unsigned);
201
202OSStatus
203box_unsigned_integer(ExceptionInformationPowerPC *, unsigned, unsigned);
204
205OSStatus
206fix_fixnum_overflow(ExceptionInformationPowerPC *, unsigned, unsigned);
207
208OSStatus
209add_fixnums(ExceptionInformationPowerPC *, unsigned, unsigned, unsigned);
210
211OSStatus
212sub_fixnums(ExceptionInformationPowerPC *, unsigned, unsigned, unsigned);
213
214OSStatus
215handle_error(ExceptionInformationPowerPC *, unsigned, unsigned, unsigned, unsigned);
216
217void
218adjust_exception_pc(ExceptionInformationPowerPC *, int);
219
220
221/* PPC instructions */
222#define match_instr(instr, mask, target)   (((instr) & (mask)) == (target))
223#define RS_field(instr)  (((instr) >> 21) & 0x1f)
224#define RT_field(instr)  (RS_field(instr))
225#define TO_field(instr)  (RT_field(instr))
226#define RA_field(instr)  (((instr) >> 16) & 0x1f)
227#define RB_field(instr)  (((instr) >> 11) & 0x1f)
228#define D_field(instr)   ((instr) & 0xffff)
229
230#define RT(val) ((val & 0x1f) << 21)
231#define RS(val) (RT(val))
232#define RA(val) ((val & 0x1f) << 16)
233#define RB(val) ((val & 0x1f) << 11)
234#define D(val) (val & 0xffff)
235
236#define RS_MASK RS(-1)
237#define RT_MASK RS_MASK
238#define TO_MASK RS_MASK
239#define RA_MASK RA(-1)
240#define RB_MASK RB(-1)
241#define D_MASK  D(-1)
242
243
244
245#define OP(x) (((x) & 0x3f) << 26)
246#define OP_MASK OP (0x3f)
247
248/* Main opcode + TO field of a D form instruction */
249#define OPTO(x,to) (OP(x) | (((to) & 0x1f) << 21))
250#define OPTO_MASK (OP_MASK | TO_MASK)
251#define OPTORA(x,to,ra) (OPTO(x,to) | ((ra) << 16))
252#define OPTORA_MASK (OP_TO_MASK | RA_MASK)
253
254
255
256
257/* An X form instruction.  */
258#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
259
260/* An X form instruction with the RC bit specified.  */
261#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
262
263/* The mask for an X form instruction.  */
264#define X_MASK XRC(0x3f, 0x3ff, 1)
265
266/* An XO form instruction */
267#define XO(op, xop, oe, rc) \
268  (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1))
269#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
270
271
272
273/* The bits in the TO field of a TW or TWI instruction */
274#define TO_LT (1<<4)            /* signed < */
275#define TO_GT (1<<3)            /* signed > */
276#define TO_EQ (1<<2)            /* = */
277#define TO_LO (1<<1)            /* unsigned < */
278#define TO_HI (1<<0)            /* unsigned > */
279#define TO_NE (TO_LT|TO_GT)
280
281/* True if major opcode of "instr" is "op" */
282#define major_opcode_p(instr, op) match_instr((instr),OP_MASK,OP(op))
283
284/* True if "instr" is an X form instruction with major opcode "major"
285   and minor opcode "minor" */
286#define X_opcode_p(instr,major,minor) match_instr((instr),X_MASK,X(major,minor))
287
288#define major_opcode_TWI 3
289#define major_opcode_ADDI 14
290#define major_opcode_RLWINM 21
291#define major_opcode_X31 31             /* an "X" form instruction; see minor opcode */
292#define major_opcode_LWZ 32
293#define major_opcode_LBZ 34
294#define major_opcode_STW 36
295#define major_opcode_STWU 37
296#define major_opcode_FPU_SINGLE 59
297#define major_opcode_FPU_DOUBLE 63
298
299#define minor_opcode_TW 4
300#define minor_opcode_SUBF 40
301#define minor_opcode_STWX 151
302#define minor_opcode_STWUX 183
303
304
305#define D_instruction(major,rt,ra,imm) (OP(major)|((rt)<<21)|((ra)<<16)|((imm)&D_MASK))
306#define TWI_instruction(rt,ra,imm)     D_instruction(major_opcode_TWI,rt,ra,imm)
307#define LBZ_instruction(rt,ra,imm)     D_instruction(major_opcode_LBZ,rt,ra,imm)
308#define LWZ_instruction(rt,ra,imm)     D_instruction(major_opcode_LWZ,rt,ra,imm)
309
310#define D_RT_IMM_MASK                  (OP_MASK|RT_MASK|D_MASK)
311#define D_RA_IMM_MASK                  (OP_MASK|RA_MASK|D_MASK)
312
313#define X_instruction(major,minor,rt,ra,rb) (X(major,minor)|((rt)<<21)|((ra)<<16)|((rb)<<11))
314
315#define unmasked_register              0
316
317#define LISP_BREAK_INSTRUCTION 0x7F810808
318
319/* twllt allocptr,allocbase */
320#define ALLOC_TRAP_INSTRUCTION 0x7C495008
321
322/* twlgei allocptr,0 */
323#define GC_TRAP_INSTRUCTION 0x0CA90000
324
325/* clrrwi allocptr,allocptr,3 */
326#define UNTAG_ALLOCPTR_INSTRUCTION 0x55290038
327
328/* stw rX,misc_header_offset(allocptr) */
329#define STORE_HEADER_ALLOCPTR_INSTRUCTION 0x9009FFFA
330#define STORE_HEADER_ALLOCPTR_MASK D_RA_IMM_MASK
331
332/* stw rX,cons.cXr(allocptr) */
333#define STORE_CAR_ALLOCPTR_INSTRUCTION 0x90090003
334#define STORE_CDR_ALLOCPTR_INSTRUCTION 0x9009ffff
335#define STORE_CXR_ALLOCPTR_MASK D_RA_IMM_MASK
336
337/* stwu sp,-16(sp) */
338#define CREATE_LISP_FRAME_INSTRUCTION 0x9421FFF0
339
340void Bug(ExceptionInformationPowerPC *, const char *format_string, ...);
341int gc_from_xp(ExceptionInformationPowerPC *);
342int purify_from_xp(ExceptionInformationPowerPC *);
343int impurify_from_xp(ExceptionInformationPowerPC *);
344
345typedef char* vector_buf;
346
347void put_altivec_registers(vector_buf);
348void get_altivec_registers(vector_buf);
349
350void pc_luser_xp(ExceptionInformation *, TCR *);
351
352int altivec_available;
353
354/* Yet another way to look at a branch instruction ... */
355typedef union {
356  struct {unsigned op:6, li:24, aa:1, lk:1;} b;
357  unsigned opcode;
358} branch_instruction;
359
360
361
362void
363Fatal(StringPtr, StringPtr);
364
365
366Ptr
367allocate(unsigned);
368
369Ptr
370zalloc(unsigned);
371
372void
373deallocate(Ptr);
374
375  /* Enable exceptions (at least, enable another thread's attempts to
376     suspend this one) by restoring the signal mask.
377  */
378
379
380#define ALLOW_EXCEPTIONS(context) \
381  pthread_sigmask(SIG_SETMASK, &context->uc_sigmask, NULL);
382
383#ifdef DARWIN
384#define SIGNAL_FOR_PROCESS_INTERRUPT SIGEMT
385#endif
386#ifdef LINUX
387#define SIGNAL_FOR_PROCESS_INTERRUPT SIGPWR
388#endif
389
390
391#ifdef LINUX
392register void *current_r2 __asm__("r2");
393#endif
394
395#endif
396
397#define debug_entry_exception 0
398#define debug_entry_bug -1
399#define debug_entry_dbg -2
Note: See TracBrowser for help on using the repository browser.