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

Last change on this file since 7282 was 7282, checked in by gb, 12 years ago

Don't use sigaltstack on any x86-64 platform: even if it works, it makes
it harder to deal with exceptions in foreign code (we've often gotten
segfaults from running out of space on the alt stack, the mechanism
isn't reentrant, etc.)

Try to report cases where the kernel debugger is entered due to an
exception in foreign code. Todo: make it less tempting to use (L)
in that case, maybe try to make backtrace find saved_rbp from tcr on x86-64,
etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1/*
2   Copyright (C) 2005 Clozure Associates
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
17typedef u8_t opcode, *pc;
18
19#ifdef LINUX
20#ifdef X8664
21#define xpGPRvector(x) ((natural *)(&((x)->uc_mcontext.gregs)))
22#define xpGPR(x,gprno) (xpGPRvector(x)[gprno])
23#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (natural)(new)
24#define xpPC(x) (xpGPR(x,Iip))
25#define xpMMXreg(x,n)  *((natural *)(&((x)->uc_mcontext.fpregs->_st[n])))
26#endif
27#endif
28
29#ifdef DARWIN
30#define DARWIN_USE_PSEUDO_SIGRETURN 1
31#include <sys/syscall.h>
32#define DarwinSigReturn(context) syscall(0x2000000|SYS_sigreturn,context,0x1e)
33#ifdef X8664
34#define xpGPRvector(x) ((natural *)(&(UC_MCONTEXT(x)->__ss.__rax)))
35#define xpGPR(x,gprno) (xpGPRvector(x)[gprno])
36#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (natural)(new)
37#define xpPC(x) (xpGPR(x,Iip))
38#define xpFPRvector(x) ((natural *)(&(UC_MCONTEXT(x)->__fs.__fpu_xmm0)))
39#define xpMMXreg(x,n)  (xpFPRvector(x)[n])
40#endif
41#include <mach/mach.h>
42#include <mach/mach_error.h>
43#include <mach/machine/thread_state.h>
44#include <mach/machine/thread_status.h>
45
46pthread_mutex_t *mach_exception_lock;
47
48#endif
49
50#ifdef FREEBSD
51#ifdef X8664
52#include <machine/fpu.h>
53#define xpGPRvector(x) ((natural *)(&((x)->uc_mcontext)))
54#define xpGPR(x,gprno) (xpGPRvector(x)[gprno])
55#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (natural)(new)
56#define xpPC(x) xpGPR(x,Iip)
57#define xpMMXreg(x,n) *((natural *)(&(((struct savefpu *)(&(x)->uc_mcontext.mc_fpstate))->sv_fp[n])))
58#define xpXMMregs(x)(&(((struct savefpu *)(&(x)->uc_mcontext.mc_fpstate))->sv_xmm[0]))
59#endif
60#endif
61
62#ifdef SOLARIS
63#ifdef X8664
64#define xpGPRvector(x) ((x)->uc_mcontext.gregs)
65#define xpGPR(x,gprno) (xpGPRvector(x)[gprno])
66#define set_xpGPR(x,gpr,new) xpGPR((x),(gpr)) = (natural)(new)
67#define xpPC(x) xpGPR(x,Iip)
68#define xpMMXreg(x,n)  *((natural *)(&(x)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.st[n]))
69#endif
70#endif
71
72
73#ifdef DARWIN
74#define SIGNAL_FOR_PROCESS_INTERRUPT SIGEMT
75#endif
76#ifdef LINUX
77#define SIGNAL_FOR_PROCESS_INTERRUPT SIGPWR
78#endif
79#ifdef FREEBSD
80#define SIGNAL_FOR_PROCESS_INTERRUPT SIGEMT
81#endif
82#ifdef SOLARIS
83#define SIGNAL_FOR_PROCESS_INTERRUPT SIGEMT
84#endif
85
86
87void switch_to_foreign_stack(void*, ...);
88
89#define INTN_OPCODE 0xcd
90
91#define UUO_GC_TRAP    0xc4
92#define UUO_ALLOC_TRAP 0xc5
93#define UUO_DEBUG_TRAP 0xca
94#define UUO_DEBUG_TRAP_WITH_STRING 0xcd
95
96#define XUUO_OPCODE_0 0x0f
97#define XUUO_OPCODE_1 0x0b
98
99#define XUUO_TLB_TOO_SMALL 1
100#define XUUO_INTERRUPT_NOW 2
101
102void
103pc_luser_xp(ExceptionInformation*, TCR*, signed_natural*);
104
105
106typedef enum {
107  ID_unrecognized_alloc_instruction,
108  ID_load_allocptr_reg_from_tcr_save_allocptr_instruction,
109  ID_compare_allocptr_reg_to_tcr_save_allocbase_instruction,
110  ID_branch_around_alloc_trap_instruction,
111  ID_alloc_trap_instruction,
112  ID_set_allocptr_header_instruction,
113  ID_clear_tcr_save_allocptr_tag_instruction
114} alloc_instruction_id;
115
116#ifdef LINUX
117#define SIGNUM_FOR_INTN_TRAP SIGSEGV
118#define IS_MAYBE_INT_TRAP(info,xp) (((info->si_code) &0x7f) == 0)
119#define SIGRETURN(context)
120#endif
121
122#ifdef FREEBSD
123extern void freebsd_sigreturn(ExceptionInformation *);
124#define SIGNUM_FOR_INTN_TRAP SIGBUS
125#define IS_MAYBE_INT_TRAP(info,xp) (xp->uc_mcontext.mc_trapno == T_PROTFLT)
126#define SIGRETURN(context) freebsd_sigreturn(context)
127#endif
128
129#ifdef DARWIN
130#define SIGNUM_FOR_INTN_TRAP SIGSEGV /* Not really, but our Mach handler fakes that */
131#define IS_MAYBE_INT_TRAP(info,xp) (info->si_code == EXC_I386_GPFLT)
132/* The x86 version of sigreturn just needs the context argument; the
133   hidden, magic "flavor" argument that sigtramp uses is ignored. */
134#define SIGRETURN(context) DarwinSigReturn(context)
135#endif
136
137/* Please go away. */
138#ifdef DARWIN_GS_HACK
139extern Boolean ensure_gs_pthread(void);
140extern void set_gs_address(void *);
141#endif
142
143
144/* sigaltstack isn't thread-specific on The World's Most Advanced OS */
145#ifdef DARWIN
146#undef USE_SIGALTSTACK
147#else
148/* #define USE_SIGALTSTACK 1 */
149#undef USE_SIGALTSTACK
150#endif
151
152#ifdef USE_SIGALTSTACK
153void setup_sigaltstack(area *);
154#endif
155
156/* recognizing the function associated with a tagged return address */
157/* now involves recognizinig an "(lea (@ disp (% rip)) (% rn))" */
158/* instruction at the tra */
159
160#define RECOVER_FN_FROM_RIP_LENGTH 7 /* the instruction is 7 bytes long */
161#define RECOVER_FN_FROM_RIP_DISP_OFFSET 3 /* displacement word is 3 bytes in */
162#define RECOVER_FN_FROM_RIP_WORD0 0x8d4c /* 0x4c 0x8d, little-endian */
163#define RECOVER_FN_FROM_RIP_BYTE2 0x2d  /* third byte of opcode */
Note: See TracBrowser for help on using the repository browser.