Improved a bit the folder browsing implementation.
[wine.git] / dlls / ntdll / signal_sparc.c
blobd64b5c06bc7121dd933c44e20be98a55b5d308a9
1 /*
2 * Sparc signal handling routines
3 *
4 * Copyright 1999 Ulrich Weigand
5 */
7 #ifdef __sparc__
9 #include "config.h"
11 #include <errno.h>
12 #include <signal.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <stdio.h>
17 #include <sys/ucontext.h>
19 #include "wine/exception.h"
20 #include "winnt.h"
21 #include "winbase.h"
22 #include "global.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 /**********************************************************************
34 * save_context
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 /**********************************************************************
92 * restore_context
94 static void restore_context( CONTEXT *context, ucontext_t *ucontext )
96 /* FIXME */
99 /**********************************************************************
100 * save_fpu
102 static void save_fpu( CONTEXT *context, ucontext_t *ucontext )
104 /* FIXME */
107 /**********************************************************************
108 * restore_fpu
110 static void restore_fpu( CONTEXT *context, ucontext_t *ucontext )
112 /* FIXME */
116 /**********************************************************************
117 * segv_handler
119 * Handler for SIGSEGV.
121 static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
123 EXCEPTION_RECORD rec;
124 CONTEXT context;
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 /**********************************************************************
144 * bus_handler
146 * Handler for SIGBUS.
148 static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
150 EXCEPTION_RECORD rec;
151 CONTEXT context;
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;
161 else
162 rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
164 EXC_RtlRaiseException( &rec, &context );
165 restore_context( &context, ucontext );
168 /**********************************************************************
169 * ill_handler
171 * Handler for SIGILL.
173 static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
175 EXCEPTION_RECORD rec;
176 CONTEXT context;
178 switch ( info->si_code )
180 default:
181 case ILL_ILLOPC:
182 case ILL_ILLOPN:
183 case ILL_ILLADR:
184 case ILL_ILLTRP:
185 rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
186 break;
188 case ILL_PRVOPC:
189 case ILL_PRVREG:
190 rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
191 break;
193 case ILL_BADSTK:
194 rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
195 break;
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 /**********************************************************************
209 * trap_handler
211 * Handler for SIGTRAP.
213 static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
215 EXCEPTION_RECORD rec;
216 CONTEXT context;
218 switch ( info->si_code )
220 case TRAP_TRACE:
221 rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
222 break;
223 case TRAP_BRKPT:
224 default:
225 rec.ExceptionCode = EXCEPTION_BREAKPOINT;
226 break;
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 /**********************************************************************
240 * fpe_handler
242 * Handler for SIGFPE.
244 static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
246 EXCEPTION_RECORD rec;
247 CONTEXT context;
249 switch ( info->si_code )
251 case FPE_FLTSUB:
252 rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
253 break;
254 case FPE_INTDIV:
255 rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
256 break;
257 case FPE_INTOVF:
258 rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
259 break;
260 case FPE_FLTDIV:
261 rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
262 break;
263 case FPE_FLTOVF:
264 rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
265 break;
266 case FPE_FLTUND:
267 rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
268 break;
269 case FPE_FLTRES:
270 rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
271 break;
272 case FPE_FLTINV:
273 default:
274 rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
275 break;
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 /**********************************************************************
291 * int_handler
293 * Handler for SIGINT.
295 static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
297 EXCEPTION_RECORD rec;
298 CONTEXT context;
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 /***********************************************************************
312 * set_handler
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 /**********************************************************************
330 * SIGNAL_Init
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;
345 return TRUE;
347 error:
348 perror("sigaction");
349 return FALSE;
352 /**********************************************************************
353 * DbgBreakPoint (NTDLL)
355 void WINAPI DbgBreakPoint(void)
357 /* FIXME */
360 /**********************************************************************
361 * DbgUserBreakPoint (NTDLL)
363 void WINAPI DbgUserBreakPoint(void)
365 /* FIXME */
368 #endif /* __sparc__ */