'sizeof type' is best avoided as it won't always compile (e.g. 'int
[wine] / dlls / ntdll / signal_powerpc.c
1 /*
2  * PowerPC signal handling routines
3  *
4  * Copyright 2002 Marcus Meissner, SuSE Linux AG
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #ifdef __powerpc__
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <signal.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32
33 #ifdef HAVE_SYS_PARAM_H
34 # include <sys/param.h>
35 #endif
36 #ifdef HAVE_SYSCALL_H
37 # include <syscall.h>
38 #else
39 # ifdef HAVE_SYS_SYSCALL_H
40 #  include <sys/syscall.h>
41 # endif
42 #endif
43
44 #ifdef HAVE_SYS_VM86_H
45 # include <sys/vm86.h>
46 #endif
47
48 #ifdef HAVE_SYS_SIGNAL_H
49 # include <sys/signal.h>
50 #endif
51
52 #include "windef.h"
53 #include "winternl.h"
54 #include "wine/library.h"
55 #include "wine/exception.h"
56 #include "selectors.h"
57 #include "stackframe.h"
58 #include "global.h"
59 #include "miscemu.h"
60 #include "wine/debug.h"
61
62 WINE_DEFAULT_DEBUG_CHANNEL(seh);
63
64
65 /***********************************************************************
66  * signal context platform-specific definitions
67  */
68 #ifdef linux
69 # warning Please define registers for your platform linux ppc some are missing
70
71 typedef struct ucontext SIGCONTEXT;
72
73 # define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
74 # define HANDLER_CONTEXT (__context)
75
76 /* All Registers access - only for local access */
77 # define REG_sig(reg_name, context)             ((context)->uc_mcontext.regs->reg_name)
78
79
80 /* Gpr Registers access  */
81 # define GPR_sig(reg_num, context)              REG_sig(r##reg_num, context)
82
83 # define IAR_sig(context)                       REG_sig(nip, context)   /* Program counter */
84 # define MSR_sig(context)                       REG_sig(msr, context)   /* Machine State Register (Supervisor) */
85 # define CTR_sig(context)                       REG_sig(ctr, context)   /* Count register */
86
87 # define XER_sig(context)                       XER_sig not defined on your platform /* Link register */
88 # define LR_sig(context)                        LR_sig not defined on your platform  /* User's integer exception register */
89 # define CR_sig(context)                        CR_sig not defined on your platform  /* Condition register */
90
91 /* Float Registers access  */
92 # define FLOAT_sig(reg_num, context)            FLOAT_sig not defined on your platform /* Float registers */
93
94 # define FPSCR_sig(reg_num, context)            FPSCR_sig not defined on your platform /* Float registers */
95
96 /* Exception Registers access */
97 # define DAR_sig(context)                       DAR_sig not defined on your platform
98 # define DSISR_sig(context)                     DSISR_sig not defined on your platform
99 # define TRAP_sig(context)                      TRAP_sig not defined on your platform
100
101 #endif /* linux */
102
103 #ifdef __darwin__
104
105 # include <sys/ucontext.h>
106
107 # include <sys/types.h>
108 # include <signal.h>
109 typedef siginfo_t siginfo;
110
111 typedef struct ucontext SIGCONTEXT;
112
113
114 # define HANDLER_DEF(name) void name( int __signal, siginfo *__siginfo, SIGCONTEXT *__context )
115 # define HANDLER_CONTEXT (__context)
116
117 /* All Registers access - only for local access */
118 # define REG_sig(reg_name, context)             ((context)->uc_mcontext->ss.reg_name)
119 # define FLOATREG_sig(reg_name, context)        ((context)->uc_mcontext->fs.reg_name)
120 # define EXCEPREG_sig(reg_name, context)        ((context)->uc_mcontext->es.reg_name)
121 # define VECREG_sig(reg_name, context)          ((context)->uc_mcontext->vs.reg_name)
122
123 /* Gpr Registers access */
124 # define GPR_sig(reg_num, context)              REG_sig(r##reg_num, context)
125
126 # define IAR_sig(context)                       REG_sig(srr0, context)  /* Program counter */
127 # define MSR_sig(context)                       REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
128 # define CTR_sig(context)                       REG_sig(ctr, context)
129
130 # define XER_sig(context)                       REG_sig(xer, context) /* Link register */
131 # define LR_sig(context)                        REG_sig(lr, context)  /* User's integer exception register */
132 # define CR_sig(context)                        REG_sig(cr, context)  /* Condition register */
133
134 /* Float Registers access */
135 # define FLOAT_sig(reg_num, context)            FLOATREG_sig(fpregs[reg_num], context)
136
137 # define FPSCR_sig(context)                     ((double)FLOATREG_sig(fpscr, context))
138
139 /* Exception Registers access */
140 # define DAR_sig(context)                       EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
141 # define DSISR_sig(context)                     EXCEPREG_sig(dsisr, context)
142 # define TRAP_sig(context)                      EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
143
144 /* Signal defs : Those are undefined on darwin
145 SIGBUS
146 #undef BUS_ADRERR
147 #undef BUS_OBJERR
148 SIGILL
149 #undef ILL_ILLOPN
150 #undef ILL_ILLTRP
151 #undef ILL_ILLADR
152 #undef ILL_COPROC
153 #undef ILL_PRVREG
154 #undef ILL_BADSTK
155 SIGTRAP
156 #undef TRAP_BRKPT
157 #undef TRAP_TRACE
158 SIGFPE
159 */
160
161 #endif /* __darwin__ */
162
163
164
165 typedef int (*wine_signal_handler)(unsigned int sig);
166
167 static wine_signal_handler handlers[256];
168
169 extern void WINAPI EXC_RtlRaiseException( PEXCEPTION_RECORD, PCONTEXT );
170
171 /***********************************************************************
172  *           dispatch_signal
173  */
174 inline static int dispatch_signal(unsigned int sig)
175 {
176     if (handlers[sig] == NULL) return 0;
177     return handlers[sig](sig);
178 }
179
180 /***********************************************************************
181  *           save_context
182  *
183  * Set the register values from a sigcontext.
184  */
185 static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
186 {
187
188 #define C(x) context->Gpr##x = GPR_sig(x,sigcontext)
189         /* Save Gpr registers */
190         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
191         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
192         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
193         C(31);
194 #undef C
195
196         context->Iar = IAR_sig(sigcontext);  /* Program Counter */
197         context->Msr = MSR_sig(sigcontext);  /* Machine State Register (Supervisor) */
198         context->Ctr = CTR_sig(sigcontext);
199         
200         context->Xer = XER_sig(sigcontext);
201         context->Lr  = LR_sig(sigcontext);
202         context->Cr  = CR_sig(sigcontext);
203         
204         /* Saving Exception regs */
205         context->Dar   = DAR_sig(sigcontext);
206         context->Dsisr = DSISR_sig(sigcontext);
207         context->Trap  = TRAP_sig(sigcontext);
208 }
209
210
211 /***********************************************************************
212  *           restore_context
213  *
214  * Build a sigcontext from the register values.
215  */
216 static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
217 {
218
219 #define C(x)  GPR_sig(x,sigcontext) = context->Gpr##x
220         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
221         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
222         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
223         C(31);
224 #undef C
225
226         IAR_sig(sigcontext) = context->Iar;  /* Program Counter */
227         MSR_sig(sigcontext) = context->Msr;  /* Machine State Register (Supervisor) */
228         CTR_sig(sigcontext) = context->Ctr;
229         
230         XER_sig(sigcontext) = context->Xer;
231         LR_sig(sigcontext) = context->Lr;
232         CR_sig(sigcontext) = context->Cr;
233         
234         /* Setting Exception regs */
235         DAR_sig(sigcontext) = context->Dar;
236         DSISR_sig(sigcontext) = context->Dsisr;
237         TRAP_sig(sigcontext) = context->Trap;
238 }
239
240
241 /***********************************************************************
242  *           save_fpu
243  *
244  * Set the FPU context from a sigcontext.
245  */
246 inline static void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
247 {
248 #define C(x)   context->Fpr##x = FLOAT_sig(x,sigcontext)
249         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
250         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
251         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
252         C(31);
253 #undef C
254         context->Fpscr = FPSCR_sig(sigcontext);
255 }
256
257
258 /***********************************************************************
259  *           restore_fpu
260  *
261  * Restore the FPU context to a sigcontext.
262  */
263 inline static void restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
264 {
265 #define C(x)  FLOAT_sig(x,sigcontext) = context->Fpr##x
266         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
267         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
268         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
269         C(31);
270 #undef C
271         FPSCR_sig(sigcontext) = context->Fpscr;
272 }
273
274
275 /**********************************************************************
276  *              get_fpu_code
277  *
278  * Get the FPU exception code from the FPU status.
279  */
280 static inline DWORD get_fpu_code( const CONTEXT *context )
281 {
282     DWORD status  = context->Fpscr;
283
284     if (status & 0x01)  /* IE */
285     {
286         if (status & 0x40)  /* SF */
287             return EXCEPTION_FLT_STACK_CHECK;
288         else
289             return EXCEPTION_FLT_INVALID_OPERATION;
290     }
291     if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND;  /* DE flag */
292     if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO;    /* ZE flag */
293     if (status & 0x08) return EXCEPTION_FLT_OVERFLOW;          /* OE flag */
294     if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW;         /* UE flag */
295     if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT;    /* PE flag */
296     return EXCEPTION_FLT_INVALID_OPERATION;  /* generic error */
297 }
298
299 /**********************************************************************
300  *              do_segv
301  *
302  * Implementation of SIGSEGV handler.
303  */
304 static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr )
305 {
306     EXCEPTION_RECORD rec;
307     DWORD page_fault_code = EXCEPTION_ACCESS_VIOLATION;
308
309     rec.ExceptionRecord  = NULL;
310     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
311     rec.ExceptionAddress = addr;
312     rec.NumberParameters = 0;
313     
314     switch (trap) {
315     case SIGSEGV:
316         switch ( code & 0xffff ) {
317         case SEGV_MAPERR:
318         case SEGV_ACCERR:
319                 rec.NumberParameters = 2;
320                 rec.ExceptionInformation[0] = 0; /* FIXME ? */
321                 rec.ExceptionInformation[1] = (DWORD)addr;
322                 if (!(page_fault_code=VIRTUAL_HandleFault(addr)))
323                         return;
324                 rec.ExceptionCode = page_fault_code;
325                 break;
326         default:FIXME("Unhandled SIGSEGV/%x\n",code);
327                 break;
328         }
329         break;
330     case SIGBUS:
331         switch ( code & 0xffff ) {
332         case BUS_ADRALN:
333                 rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
334                 break;
335 #ifdef BUS_ADRERR
336         case BUS_ADRERR:
337 #endif
338 #ifdef BUS_OBJERR
339         case BUS_OBJERR:
340                 /* FIXME: correct for all cases ? */
341                 rec.NumberParameters = 2;
342                 rec.ExceptionInformation[0] = 0; /* FIXME ? */
343                 rec.ExceptionInformation[1] = (DWORD)addr;
344                 if (!(page_fault_code=VIRTUAL_HandleFault(addr)))
345                         return;
346                 rec.ExceptionCode = page_fault_code;
347                 break;
348 #endif
349         default:FIXME("Unhandled SIGBUS/%x\n",code);
350                 break;
351         }
352         break;
353     case SIGILL:
354         switch ( code & 0xffff ) {
355         case ILL_ILLOPC: /* illegal opcode */
356 #ifdef ILL_ILLOPN
357         case ILL_ILLOPN: /* illegal operand */
358 #endif
359 #ifdef ILL_ILLADR
360         case ILL_ILLADR: /* illegal addressing mode */
361 #endif
362 #ifdef ILL_ILLTRP
363         case ILL_ILLTRP: /* illegal trap */
364 #endif
365 #ifdef ILL_COPROC
366         case ILL_COPROC: /* coprocessor error */
367 #endif
368                 rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
369                 break;
370         case ILL_PRVOPC: /* privileged opcode */
371 #ifdef ILL_PRVREG
372         case ILL_PRVREG: /* privileged register */
373 #endif
374                 rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
375                 break;
376 #ifdef ILL_BADSTK
377         case ILL_BADSTK: /* internal stack error */
378                 rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
379                 break;
380 #endif
381         default:FIXME("Unhandled SIGILL/%x\n", code);
382                 break;
383         }
384         break;
385     }
386     EXC_RtlRaiseException( &rec, context );
387 }
388
389 /**********************************************************************
390  *              do_trap
391  *
392  * Implementation of SIGTRAP handler.
393  */
394 static void do_trap( CONTEXT *context, int code, void * addr )
395 {
396     EXCEPTION_RECORD rec;
397
398     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
399     rec.ExceptionRecord  = NULL;
400     rec.ExceptionAddress = addr;
401     rec.NumberParameters = 0;
402
403     /* FIXME: check if we might need to modify PC */
404     switch (code & 0xffff) {
405 #ifdef TRAP_BRKPT
406     case TRAP_BRKPT:
407         rec.ExceptionCode = EXCEPTION_BREAKPOINT;
408         break;
409 #endif
410 #ifdef TRAP_TRACE
411     case TRAP_TRACE:
412         rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
413         break;
414 #endif
415     default:FIXME("Unhandled SIGTRAP/%x\n", code);
416                 break;
417     }
418     EXC_RtlRaiseException( &rec, context );
419 }
420
421 /**********************************************************************
422  *              do_trap
423  *
424  * Implementation of SIGFPE handler.
425  */
426 static void do_fpe( CONTEXT *context, int code, void * addr )
427 {
428     EXCEPTION_RECORD rec;
429
430     switch ( code  & 0xffff ) {
431 #ifdef FPE_FLTSUB
432     case FPE_FLTSUB:
433         rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
434         break;
435 #endif
436 #ifdef FPE_INTDIV
437     case FPE_INTDIV:
438         rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
439         break;
440 #endif
441 #ifdef FPE_INTOVF
442     case FPE_INTOVF:
443         rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
444         break;
445 #endif
446 #ifdef FPE_FLTDIV
447     case FPE_FLTDIV:
448         rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
449         break;
450 #endif
451 #ifdef FPE_FLTOVF
452     case FPE_FLTOVF:
453         rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
454         break;
455 #endif
456 #ifdef FPE_FLTUND
457     case FPE_FLTUND:
458         rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
459         break;
460 #endif
461 #ifdef FPE_FLTRES
462     case FPE_FLTRES:
463         rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
464         break;
465 #endif
466 #ifdef FPE_FLTINV
467     case FPE_FLTINV:
468 #endif
469     default:
470         rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
471         break;
472     }
473     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
474     rec.ExceptionRecord  = NULL;
475     rec.ExceptionAddress = addr;
476     rec.NumberParameters = 0;
477     EXC_RtlRaiseException( &rec, context );
478 }
479
480 /**********************************************************************
481  *              segv_handler
482  *
483  * Handler for SIGSEGV and related errors.
484  */
485 static HANDLER_DEF(segv_handler)
486 {
487     CONTEXT context;
488     save_context( &context, HANDLER_CONTEXT );
489     do_segv( &context, __siginfo->si_signo, __siginfo->si_errno, __siginfo->si_code, __siginfo->si_addr );
490     restore_context( &context, HANDLER_CONTEXT );
491 }
492
493 /**********************************************************************
494  *              trap_handler
495  *
496  * Handler for SIGTRAP.
497  */
498 static HANDLER_DEF(trap_handler)
499 {
500     CONTEXT context;
501     save_context( &context, HANDLER_CONTEXT );
502     do_trap( &context, __siginfo->si_code, __siginfo->si_addr );
503     restore_context( &context, HANDLER_CONTEXT );
504 }
505
506 /**********************************************************************
507  *              fpe_handler
508  *
509  * Handler for SIGFPE.
510  */
511 static HANDLER_DEF(fpe_handler)
512 {
513     CONTEXT context;
514     save_fpu( &context, HANDLER_CONTEXT );
515     save_context( &context, HANDLER_CONTEXT );
516     do_fpe( &context,  __siginfo->si_code, __siginfo->si_addr );
517     restore_context( &context, HANDLER_CONTEXT );
518     restore_fpu( &context, HANDLER_CONTEXT );
519 }
520
521 /**********************************************************************
522  *              int_handler
523  *
524  * Handler for SIGINT.
525  */
526 static HANDLER_DEF(int_handler)
527 {
528     if (!dispatch_signal(SIGINT))
529     {
530         EXCEPTION_RECORD rec;
531         CONTEXT context;
532
533         save_context( &context, HANDLER_CONTEXT );
534         rec.ExceptionCode    = CONTROL_C_EXIT;
535         rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
536         rec.ExceptionRecord  = NULL;
537         rec.ExceptionAddress = (LPVOID)context.Iar;
538         rec.NumberParameters = 0;
539         EXC_RtlRaiseException( &rec, &context );
540         restore_context( &context, HANDLER_CONTEXT );
541     }
542 }
543
544
545 /**********************************************************************
546  *              abrt_handler
547  *
548  * Handler for SIGABRT.
549  */
550 static HANDLER_DEF(abrt_handler)
551 {
552     EXCEPTION_RECORD rec;
553     CONTEXT context;
554
555     save_context( &context, HANDLER_CONTEXT );
556     rec.ExceptionCode    = EXCEPTION_WINE_ASSERTION;
557     rec.ExceptionFlags   = EH_NONCONTINUABLE;
558     rec.ExceptionRecord  = NULL;
559     rec.ExceptionAddress = (LPVOID)context.Iar;
560     rec.NumberParameters = 0;
561     EXC_RtlRaiseException( &rec, &context ); /* Should never return.. */
562     restore_context( &context, HANDLER_CONTEXT );
563 }
564
565
566 /**********************************************************************
567  *              term_handler
568  *
569  * Handler for SIGTERM.
570  */
571 static HANDLER_DEF(term_handler)
572 {
573     SYSDEPS_AbortThread(0);
574 }
575
576
577 /**********************************************************************
578  *              usr1_handler
579  *
580  * Handler for SIGUSR1, used to signal a thread that it got suspended.
581  */
582 static HANDLER_DEF(usr1_handler)
583 {
584     LARGE_INTEGER timeout;
585
586     /* wait with 0 timeout, will only return once the thread is no longer suspended */
587     timeout.QuadPart = 0;
588     NtWaitForMultipleObjects( 0, NULL, FALSE, FALSE, &timeout );
589 }
590
591
592 /***********************************************************************
593  *           set_handler
594  *
595  * Set a signal handler
596  */
597 static int set_handler( int sig, int have_sigaltstack, void (*func)() )
598 {
599     struct sigaction sig_act;
600
601     sig_act.sa_sigaction = func;
602     sigemptyset( &sig_act.sa_mask );
603     sigaddset( &sig_act.sa_mask, SIGINT );
604     sigaddset( &sig_act.sa_mask, SIGALRM );
605
606     sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
607
608 #ifdef SA_ONSTACK
609     if (have_sigaltstack) sig_act.sa_flags |= SA_ONSTACK;
610 #endif
611     return sigaction( sig, &sig_act, NULL );
612 }
613
614
615 /***********************************************************************
616  *           __wine_set_signal_handler   (NTDLL.@)
617  */
618 int __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
619 {
620     if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
621     if (handlers[sig] != NULL) return -2;
622     handlers[sig] = wsh;
623     return 0;
624 }
625
626
627 /**********************************************************************
628  *              SIGNAL_Init
629  */
630 BOOL SIGNAL_Init(void)
631 {
632     int have_sigaltstack = 0;
633
634 #ifdef HAVE_SIGALTSTACK
635     struct sigaltstack ss;
636     if ((ss.ss_sp = NtCurrentTeb()->signal_stack))
637     {
638         ss.ss_size  = SIGNAL_STACK_SIZE;
639         ss.ss_flags = 0;
640         if (!sigaltstack(&ss, NULL)) have_sigaltstack = 1;
641     }
642 #endif  /* HAVE_SIGALTSTACK */
643
644     if (set_handler( SIGINT,  have_sigaltstack, (void (*)())int_handler ) == -1) goto error;
645     if (set_handler( SIGFPE,  have_sigaltstack, (void (*)())fpe_handler ) == -1) goto error;
646     if (set_handler( SIGSEGV, have_sigaltstack, (void (*)())segv_handler ) == -1) goto error;
647     if (set_handler( SIGILL,  have_sigaltstack, (void (*)())segv_handler ) == -1) goto error;
648     if (set_handler( SIGABRT, have_sigaltstack, (void (*)())abrt_handler ) == -1) goto error;
649     if (set_handler( SIGTERM, have_sigaltstack, (void (*)())term_handler ) == -1) goto error;
650     if (set_handler( SIGUSR1, have_sigaltstack, (void (*)())usr1_handler ) == -1) goto error;
651 #ifdef SIGBUS
652     if (set_handler( SIGBUS,  have_sigaltstack, (void (*)())segv_handler ) == -1) goto error;
653 #endif
654 #ifdef SIGTRAP
655     if (set_handler( SIGTRAP, have_sigaltstack, (void (*)())trap_handler ) == -1) goto error;
656 #endif
657
658     return TRUE;
659
660  error:
661     perror("sigaction");
662     return FALSE;
663 }
664
665
666 /**********************************************************************
667  *              SIGNAL_Block
668  *
669  * Block the async signals.
670  */
671 void SIGNAL_Block(void)
672 {
673     sigset_t block_set;
674
675     sigemptyset( &block_set );
676     sigaddset( &block_set, SIGALRM );
677     sigaddset( &block_set, SIGIO );
678     sigaddset( &block_set, SIGHUP );
679     sigaddset( &block_set, SIGUSR1 );
680     sigaddset( &block_set, SIGUSR2 );
681     sigprocmask( SIG_BLOCK, &block_set, NULL );
682 }
683
684
685 /***********************************************************************
686  *           SIGNAL_Unblock
687  *
688  * Unblock signals. Called from EXC_RtlRaiseException.
689  */
690 void SIGNAL_Unblock(void)
691 {
692     sigset_t all_sigs;
693
694     sigfillset( &all_sigs );
695     sigprocmask( SIG_UNBLOCK, &all_sigs, NULL );
696 }
697
698
699 /**********************************************************************
700  *              SIGNAL_Reset
701  *
702  * Restore the default handlers.
703  */
704 void SIGNAL_Reset(void)
705 {
706     signal( SIGINT, SIG_DFL );
707     signal( SIGFPE, SIG_DFL );
708     signal( SIGSEGV, SIG_DFL );
709     signal( SIGILL, SIG_DFL );
710     signal( SIGABRT, SIG_DFL );
711     signal( SIGTERM, SIG_DFL );
712 #ifdef SIGBUS
713     signal( SIGBUS, SIG_DFL );
714 #endif
715 #ifdef SIGTRAP
716     signal( SIGTRAP, SIG_DFL );
717 #endif
718 }
719
720
721 /**********************************************************************
722  *              __wine_enter_vm86   (NTDLL.@)
723  */
724 void __wine_enter_vm86( CONTEXT *context )
725 {
726     MESSAGE("vm86 mode not supported on this platform\n");
727 }
728
729 /**********************************************************************
730  *              DbgBreakPoint   (NTDLL.@)
731  */
732 void WINAPI DbgBreakPoint(void)
733 {
734      kill(getpid(), SIGTRAP);
735 }
736
737 /**********************************************************************
738  *              DbgUserBreakPoint   (NTDLL.@)
739  */
740 void WINAPI DbgUserBreakPoint(void)
741 {
742      kill(getpid(), SIGTRAP);
743 }
744
745 #endif  /* __powerpc__ */