2 * Sparc signal handling routines
4 * Copyright 1999 Ulrich Weigand
17 #include <sys/ucontext.h>
19 #include "wine/exception.h"
23 #include "stackframe.h"
24 #include "debugtools.h"
26 DEFAULT_DEBUG_CHANNEL(seh
)
30 * FIXME: All this works only on Solaris for now
33 /**********************************************************************
36 static void save_context( CONTEXT
*context
, ucontext_t
*ucontext
)
38 /* Special registers */
39 context
->psr
= ucontext
->uc_mcontext
.gregs
[REG_PSR
];
40 context
->pc
= ucontext
->uc_mcontext
.gregs
[REG_PC
];
41 context
->npc
= ucontext
->uc_mcontext
.gregs
[REG_nPC
];
42 context
->y
= ucontext
->uc_mcontext
.gregs
[REG_Y
];
43 context
->wim
= 0; /* FIXME */
44 context
->tbr
= 0; /* FIXME */
46 /* Global registers */
47 context
->g0
= 0; /* always */
48 context
->g1
= ucontext
->uc_mcontext
.gregs
[REG_G1
];
49 context
->g2
= ucontext
->uc_mcontext
.gregs
[REG_G2
];
50 context
->g3
= ucontext
->uc_mcontext
.gregs
[REG_G3
];
51 context
->g4
= ucontext
->uc_mcontext
.gregs
[REG_G4
];
52 context
->g5
= ucontext
->uc_mcontext
.gregs
[REG_G5
];
53 context
->g6
= ucontext
->uc_mcontext
.gregs
[REG_G6
];
54 context
->g7
= ucontext
->uc_mcontext
.gregs
[REG_G7
];
56 /* Current 'out' registers */
57 context
->o0
= ucontext
->uc_mcontext
.gregs
[REG_O0
];
58 context
->o1
= ucontext
->uc_mcontext
.gregs
[REG_O1
];
59 context
->o2
= ucontext
->uc_mcontext
.gregs
[REG_O2
];
60 context
->o3
= ucontext
->uc_mcontext
.gregs
[REG_O3
];
61 context
->o4
= ucontext
->uc_mcontext
.gregs
[REG_O4
];
62 context
->o5
= ucontext
->uc_mcontext
.gregs
[REG_O5
];
63 context
->o6
= ucontext
->uc_mcontext
.gregs
[REG_O6
];
64 context
->o7
= ucontext
->uc_mcontext
.gregs
[REG_O7
];
66 /* FIXME: what if the current register window isn't saved? */
67 if ( ucontext
->uc_mcontext
.gwins
&& ucontext
->uc_mcontext
.gwins
->wbcnt
> 0 )
69 /* Current 'local' registers from first register window */
70 context
->l0
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[0];
71 context
->l1
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[1];
72 context
->l2
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[2];
73 context
->l3
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[3];
74 context
->l4
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[4];
75 context
->l5
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[5];
76 context
->l6
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[6];
77 context
->l7
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_local
[7];
79 /* Current 'in' registers from first register window */
80 context
->i0
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[0];
81 context
->i1
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[1];
82 context
->i2
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[2];
83 context
->i3
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[3];
84 context
->i4
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[4];
85 context
->i5
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[5];
86 context
->i6
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[6];
87 context
->i7
= ucontext
->uc_mcontext
.gwins
->wbuf
[0].rw_in
[7];
91 /**********************************************************************
94 static void restore_context( CONTEXT
*context
, ucontext_t
*ucontext
)
99 /**********************************************************************
102 static void save_fpu( CONTEXT
*context
, ucontext_t
*ucontext
)
107 /**********************************************************************
110 static void restore_fpu( CONTEXT
*context
, ucontext_t
*ucontext
)
116 /**********************************************************************
119 * Handler for SIGSEGV.
121 static void segv_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
123 EXCEPTION_RECORD rec
;
126 /* we want the page-fault case to be fast */
127 if ( info
->si_code
== SEGV_ACCERR
)
128 if (VIRTUAL_HandleFault( (LPVOID
)info
->si_addr
)) return;
130 save_context( &context
, ucontext
);
131 rec
.ExceptionCode
= EXCEPTION_ACCESS_VIOLATION
;
132 rec
.ExceptionRecord
= NULL
;
133 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
134 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
135 rec
.NumberParameters
= 2;
136 rec
.ExceptionInformation
[0] = 0; /* FIXME: read/write access ? */
137 rec
.ExceptionInformation
[1] = (DWORD
)info
->si_addr
;
139 EXC_RtlRaiseException( &rec
, &context
);
140 restore_context( &context
, ucontext
);
143 /**********************************************************************
146 * Handler for SIGBUS.
148 static void bus_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
150 EXCEPTION_RECORD rec
;
153 save_context( &context
, ucontext
);
154 rec
.ExceptionRecord
= NULL
;
155 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
156 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
157 rec
.NumberParameters
= 0;
159 if ( info
->si_code
== BUS_ADRALN
)
160 rec
.ExceptionCode
= EXCEPTION_DATATYPE_MISALIGNMENT
;
162 rec
.ExceptionCode
= EXCEPTION_ACCESS_VIOLATION
;
164 EXC_RtlRaiseException( &rec
, &context
);
165 restore_context( &context
, ucontext
);
168 /**********************************************************************
171 * Handler for SIGILL.
173 static void ill_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
175 EXCEPTION_RECORD rec
;
178 switch ( info
->si_code
)
185 rec
.ExceptionCode
= EXCEPTION_ILLEGAL_INSTRUCTION
;
190 rec
.ExceptionCode
= EXCEPTION_PRIV_INSTRUCTION
;
194 rec
.ExceptionCode
= EXCEPTION_STACK_OVERFLOW
;
198 save_context( &context
, ucontext
);
199 rec
.ExceptionRecord
= NULL
;
200 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
201 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
202 rec
.NumberParameters
= 0;
203 EXC_RtlRaiseException( &rec
, &context
);
204 restore_context( &context
, ucontext
);
208 /**********************************************************************
211 * Handler for SIGTRAP.
213 static void trap_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
215 EXCEPTION_RECORD rec
;
218 switch ( info
->si_code
)
221 rec
.ExceptionCode
= EXCEPTION_SINGLE_STEP
;
225 rec
.ExceptionCode
= EXCEPTION_BREAKPOINT
;
229 save_context( &context
, ucontext
);
230 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
231 rec
.ExceptionRecord
= NULL
;
232 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
233 rec
.NumberParameters
= 0;
234 EXC_RtlRaiseException( &rec
, &context
);
235 restore_context( &context
, ucontext
);
239 /**********************************************************************
242 * Handler for SIGFPE.
244 static void fpe_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
246 EXCEPTION_RECORD rec
;
249 switch ( info
->si_code
)
252 rec
.ExceptionCode
= EXCEPTION_ARRAY_BOUNDS_EXCEEDED
;
255 rec
.ExceptionCode
= EXCEPTION_INT_DIVIDE_BY_ZERO
;
258 rec
.ExceptionCode
= EXCEPTION_INT_OVERFLOW
;
261 rec
.ExceptionCode
= EXCEPTION_FLT_DIVIDE_BY_ZERO
;
264 rec
.ExceptionCode
= EXCEPTION_FLT_OVERFLOW
;
267 rec
.ExceptionCode
= EXCEPTION_FLT_UNDERFLOW
;
270 rec
.ExceptionCode
= EXCEPTION_FLT_INEXACT_RESULT
;
274 rec
.ExceptionCode
= EXCEPTION_FLT_INVALID_OPERATION
;
278 save_context( &context
, ucontext
);
279 save_fpu( &context
, ucontext
);
280 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
281 rec
.ExceptionRecord
= NULL
;
282 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
283 rec
.NumberParameters
= 0;
284 EXC_RtlRaiseException( &rec
, &context
);
285 restore_context( &context
, ucontext
);
286 restore_fpu( &context
, ucontext
);
290 /**********************************************************************
293 * Handler for SIGINT.
295 static void int_handler( int signal
, siginfo_t
*info
, ucontext_t
*ucontext
)
297 EXCEPTION_RECORD rec
;
300 save_context( &context
, ucontext
);
301 rec
.ExceptionCode
= CONTROL_C_EXIT
;
302 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
303 rec
.ExceptionRecord
= NULL
;
304 rec
.ExceptionAddress
= (LPVOID
)context
.pc
;
305 rec
.NumberParameters
= 0;
306 EXC_RtlRaiseException( &rec
, &context
);
307 restore_context( &context
, ucontext
);
311 /***********************************************************************
314 * Set a signal handler
316 static int set_handler( int sig
, void (*func
)() )
318 struct sigaction sig_act
;
320 sig_act
.sa_handler
= NULL
;
321 sig_act
.sa_sigaction
= func
;
322 sigemptyset( &sig_act
.sa_mask
);
323 sig_act
.sa_flags
= SA_SIGINFO
;
325 return sigaction( sig
, &sig_act
, NULL
);
329 /**********************************************************************
332 BOOL
SIGNAL_Init(void)
334 /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
335 signal( SIGPIPE
, SIG_IGN
);
336 /* automatic child reaping to avoid zombies */
337 signal( SIGCHLD
, SIG_IGN
);
339 if (set_handler( SIGINT
, (void (*)())int_handler
) == -1) goto error
;
340 if (set_handler( SIGFPE
, (void (*)())fpe_handler
) == -1) goto error
;
341 if (set_handler( SIGSEGV
, (void (*)())segv_handler
) == -1) goto error
;
342 if (set_handler( SIGILL
, (void (*)())ill_handler
) == -1) goto error
;
343 if (set_handler( SIGBUS
, (void (*)())bus_handler
) == -1) goto error
;
344 if (set_handler( SIGTRAP
, (void (*)())trap_handler
) == -1) goto error
;
352 /**********************************************************************
353 * DbgBreakPoint (NTDLL)
355 void WINAPI
DbgBreakPoint(void)
360 /**********************************************************************
361 * DbgUserBreakPoint (NTDLL)
363 void WINAPI
DbgUserBreakPoint(void)
368 #endif /* __sparc__ */