If using the default values, also set dwType to REG_SZ as our default
[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 "global.h"
60 #include "ntdll_misc.h"
61 #include "wine/debug.h"
62
63 WINE_DEFAULT_DEBUG_CHANNEL(seh);
64
65
66 /***********************************************************************
67  * signal context platform-specific definitions
68  */
69 #ifdef linux
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(gpr[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)                       REG_sig(xer, context) /* User's integer exception register */
88 # define LR_sig(context)                        REG_sig(link, context) /* Link register */
89 # define CR_sig(context)                        REG_sig(ccr, context) /* Condition register */
90
91 /* Float Registers access  */
92 # define FLOAT_sig(reg_num, context)            (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
93
94 # define FPSCR_sig(context)                     (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
95
96 /* Exception Registers access */
97 # define DAR_sig(context)                       REG_sig(dar, context)
98 # define DSISR_sig(context)                     REG_sig(dsisr, context)
99 # define TRAP_sig(context)                      REG_sig(trap, context)
100
101 #endif /* linux */
102
103 #ifdef __APPLE__
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 /* __APPLE__ */
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     server_abort_thread(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     NTDLL_wait_for_multiple_objects( 0, NULL, 0, &timeout );
589 }
590
591
592 /***********************************************************************
593  *           set_handler
594  *
595  * Set a signal handler
596  */
597 static int set_handler( int sig, 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     return sigaction( sig, &sig_act, NULL );
608 }
609
610
611 /***********************************************************************
612  *           __wine_set_signal_handler   (NTDLL.@)
613  */
614 int __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
615 {
616     if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
617     if (handlers[sig] != NULL) return -2;
618     handlers[sig] = wsh;
619     return 0;
620 }
621
622
623 /**********************************************************************
624  *              SIGNAL_Init
625  */
626 BOOL SIGNAL_Init(void)
627 {
628     if (set_handler( SIGINT,  (void (*)())int_handler ) == -1) goto error;
629     if (set_handler( SIGFPE,  (void (*)())fpe_handler ) == -1) goto error;
630     if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error;
631     if (set_handler( SIGILL,  (void (*)())segv_handler ) == -1) goto error;
632     if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error;
633     if (set_handler( SIGTERM, (void (*)())term_handler ) == -1) goto error;
634     if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error;
635 #ifdef SIGBUS
636     if (set_handler( SIGBUS,  (void (*)())segv_handler ) == -1) goto error;
637 #endif
638 #ifdef SIGTRAP
639     if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error;
640 #endif
641
642     return TRUE;
643
644  error:
645     perror("sigaction");
646     return FALSE;
647 }
648
649
650 /**********************************************************************
651  *              __wine_enter_vm86   (NTDLL.@)
652  */
653 void __wine_enter_vm86( CONTEXT *context )
654 {
655     MESSAGE("vm86 mode not supported on this platform\n");
656 }
657
658 /**********************************************************************
659  *              DbgBreakPoint   (NTDLL.@)
660  */
661 void WINAPI DbgBreakPoint(void)
662 {
663      kill(getpid(), SIGTRAP);
664 }
665
666 /**********************************************************************
667  *              DbgUserBreakPoint   (NTDLL.@)
668  */
669 void WINAPI DbgUserBreakPoint(void)
670 {
671      kill(getpid(), SIGTRAP);
672 }
673
674 #endif  /* __powerpc__ */