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