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