imagehlp: Forward some more 64-bit functions to dbghelp.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "ntstatus.h"
55 #define WIN32_NO_STATUS
56 #include "windef.h"
57 #include "winternl.h"
58 #include "wine/library.h"
59 #include "wine/exception.h"
60 #include "ntdll_misc.h"
61 #include "wine/debug.h"
62
63 WINE_DEFAULT_DEBUG_CHANNEL(seh);
64
65 static pthread_key_t teb_key;
66
67 /***********************************************************************
68  * signal context platform-specific definitions
69  */
70 #ifdef linux
71
72 typedef struct ucontext SIGCONTEXT;
73
74 # define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
75 # define HANDLER_CONTEXT (__context)
76
77 /* All Registers access - only for local access */
78 # define REG_sig(reg_name, context)             ((context)->uc_mcontext.regs->reg_name)
79
80
81 /* Gpr Registers access  */
82 # define GPR_sig(reg_num, context)              REG_sig(gpr[reg_num], context)
83
84 # define IAR_sig(context)                       REG_sig(nip, context)   /* Program counter */
85 # define MSR_sig(context)                       REG_sig(msr, context)   /* Machine State Register (Supervisor) */
86 # define CTR_sig(context)                       REG_sig(ctr, context)   /* Count register */
87
88 # define XER_sig(context)                       REG_sig(xer, context) /* User's integer exception register */
89 # define LR_sig(context)                        REG_sig(link, context) /* Link register */
90 # define CR_sig(context)                        REG_sig(ccr, context) /* Condition register */
91
92 /* Float Registers access  */
93 # define FLOAT_sig(reg_num, context)            (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
94
95 # define FPSCR_sig(context)                     (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
96
97 /* Exception Registers access */
98 # define DAR_sig(context)                       REG_sig(dar, context)
99 # define DSISR_sig(context)                     REG_sig(dsisr, context)
100 # define TRAP_sig(context)                      REG_sig(trap, context)
101
102 #endif /* linux */
103
104 #ifdef __APPLE__
105
106 # include <sys/ucontext.h>
107
108 # include <sys/types.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)                     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 /***********************************************************************
170  *           dispatch_signal
171  */
172 static inline int dispatch_signal(unsigned int sig)
173 {
174     if (handlers[sig] == NULL) return 0;
175     return handlers[sig](sig);
176 }
177
178 /***********************************************************************
179  *           save_context
180  *
181  * Set the register values from a sigcontext.
182  */
183 static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
184 {
185
186 #define C(x) context->Gpr##x = GPR_sig(x,sigcontext)
187         /* Save Gpr registers */
188         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
189         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
190         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
191         C(31);
192 #undef C
193
194         context->Iar = IAR_sig(sigcontext);  /* Program Counter */
195         context->Msr = MSR_sig(sigcontext);  /* Machine State Register (Supervisor) */
196         context->Ctr = CTR_sig(sigcontext);
197         
198         context->Xer = XER_sig(sigcontext);
199         context->Lr  = LR_sig(sigcontext);
200         context->Cr  = CR_sig(sigcontext);
201         
202         /* Saving Exception regs */
203         context->Dar   = DAR_sig(sigcontext);
204         context->Dsisr = DSISR_sig(sigcontext);
205         context->Trap  = TRAP_sig(sigcontext);
206 }
207
208
209 /***********************************************************************
210  *           restore_context
211  *
212  * Build a sigcontext from the register values.
213  */
214 static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
215 {
216
217 #define C(x)  GPR_sig(x,sigcontext) = context->Gpr##x
218         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
219         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
220         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
221         C(31);
222 #undef C
223
224         IAR_sig(sigcontext) = context->Iar;  /* Program Counter */
225         MSR_sig(sigcontext) = context->Msr;  /* Machine State Register (Supervisor) */
226         CTR_sig(sigcontext) = context->Ctr;
227         
228         XER_sig(sigcontext) = context->Xer;
229         LR_sig(sigcontext) = context->Lr;
230         CR_sig(sigcontext) = context->Cr;
231         
232         /* Setting Exception regs */
233         DAR_sig(sigcontext) = context->Dar;
234         DSISR_sig(sigcontext) = context->Dsisr;
235         TRAP_sig(sigcontext) = context->Trap;
236 }
237
238
239 /***********************************************************************
240  *           save_fpu
241  *
242  * Set the FPU context from a sigcontext.
243  */
244 static inline void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
245 {
246 #define C(x)   context->Fpr##x = FLOAT_sig(x,sigcontext)
247         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
248         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
249         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
250         C(31);
251 #undef C
252         context->Fpscr = FPSCR_sig(sigcontext);
253 }
254
255
256 /***********************************************************************
257  *           restore_fpu
258  *
259  * Restore the FPU context to a sigcontext.
260  */
261 static inline void restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
262 {
263 #define C(x)  FLOAT_sig(x,sigcontext) = context->Fpr##x
264         C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
265         C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
266         C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
267         C(31);
268 #undef C
269         FPSCR_sig(sigcontext) = context->Fpscr;
270 }
271
272
273 /***********************************************************************
274  *              RtlCaptureContext (NTDLL.@)
275  */
276 void WINAPI RtlCaptureContext( CONTEXT *context )
277 {
278     FIXME("not implemented\n");
279     memset( context, 0, sizeof(*context) );
280 }
281
282
283 /***********************************************************************
284  *           set_cpu_context
285  *
286  * Set the new CPU context.
287  */
288 void set_cpu_context( const CONTEXT *context )
289 {
290     FIXME("not implemented\n");
291 }
292
293
294 /***********************************************************************
295  *           copy_context
296  *
297  * Copy a register context according to the flags.
298  */
299 void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
300 {
301     if (flags & CONTEXT_CONTROL)
302     {
303         to->Msr   = from->Msr;
304         to->Ctr   = from->Ctr;
305         to->Iar   = from->Iar;
306         to->Lr    = from->Lr;
307         to->Dar   = from->Dar;
308         to->Dsisr = from->Dsisr;
309         to->Trap  = from->Trap;
310     }
311     if (flags & CONTEXT_INTEGER)
312     {
313         to->Gpr0  = from->Gpr0;
314         to->Gpr1  = from->Gpr1;
315         to->Gpr2  = from->Gpr2;
316         to->Gpr3  = from->Gpr3;
317         to->Gpr4  = from->Gpr4;
318         to->Gpr5  = from->Gpr5;
319         to->Gpr6  = from->Gpr6;
320         to->Gpr7  = from->Gpr7;
321         to->Gpr8  = from->Gpr8;
322         to->Gpr9  = from->Gpr9;
323         to->Gpr10 = from->Gpr10;
324         to->Gpr11 = from->Gpr11;
325         to->Gpr12 = from->Gpr12;
326         to->Gpr13 = from->Gpr13;
327         to->Gpr14 = from->Gpr14;
328         to->Gpr15 = from->Gpr15;
329         to->Gpr16 = from->Gpr16;
330         to->Gpr17 = from->Gpr17;
331         to->Gpr18 = from->Gpr18;
332         to->Gpr19 = from->Gpr19;
333         to->Gpr20 = from->Gpr20;
334         to->Gpr21 = from->Gpr21;
335         to->Gpr22 = from->Gpr22;
336         to->Gpr23 = from->Gpr23;
337         to->Gpr24 = from->Gpr24;
338         to->Gpr25 = from->Gpr25;
339         to->Gpr26 = from->Gpr26;
340         to->Gpr27 = from->Gpr27;
341         to->Gpr28 = from->Gpr28;
342         to->Gpr29 = from->Gpr29;
343         to->Gpr30 = from->Gpr30;
344         to->Gpr31 = from->Gpr31;
345         to->Xer   = from->Xer;
346         to->Cr    = from->Cr;
347     }
348     if (flags & CONTEXT_FLOATING_POINT)
349     {
350         to->Fpr0  = from->Fpr0;
351         to->Fpr1  = from->Fpr1;
352         to->Fpr2  = from->Fpr2;
353         to->Fpr3  = from->Fpr3;
354         to->Fpr4  = from->Fpr4;
355         to->Fpr5  = from->Fpr5;
356         to->Fpr6  = from->Fpr6;
357         to->Fpr7  = from->Fpr7;
358         to->Fpr8  = from->Fpr8;
359         to->Fpr9  = from->Fpr9;
360         to->Fpr10 = from->Fpr10;
361         to->Fpr11 = from->Fpr11;
362         to->Fpr12 = from->Fpr12;
363         to->Fpr13 = from->Fpr13;
364         to->Fpr14 = from->Fpr14;
365         to->Fpr15 = from->Fpr15;
366         to->Fpr16 = from->Fpr16;
367         to->Fpr17 = from->Fpr17;
368         to->Fpr18 = from->Fpr18;
369         to->Fpr19 = from->Fpr19;
370         to->Fpr20 = from->Fpr20;
371         to->Fpr21 = from->Fpr21;
372         to->Fpr22 = from->Fpr22;
373         to->Fpr23 = from->Fpr23;
374         to->Fpr24 = from->Fpr24;
375         to->Fpr25 = from->Fpr25;
376         to->Fpr26 = from->Fpr26;
377         to->Fpr27 = from->Fpr27;
378         to->Fpr28 = from->Fpr28;
379         to->Fpr29 = from->Fpr29;
380         to->Fpr30 = from->Fpr30;
381         to->Fpr31 = from->Fpr31;
382         to->Fpscr = from->Fpscr;
383     }
384 }
385
386
387 /***********************************************************************
388  *           context_to_server
389  *
390  * Convert a register context to the server format.
391  */
392 NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
393 {
394     DWORD flags = from->ContextFlags;  /* no CPU id? */
395
396     memset( to, 0, sizeof(*to) );
397     to->cpu = CPU_POWERPC;
398
399     if (flags & CONTEXT_CONTROL)
400     {
401         to->flags |= SERVER_CTX_CONTROL;
402         to->ctl.powerpc_regs.iar   = from->Iar;
403         to->ctl.powerpc_regs.msr   = from->Msr;
404         to->ctl.powerpc_regs.ctr   = from->Ctr;
405         to->ctl.powerpc_regs.lr    = from->Lr;
406         to->ctl.powerpc_regs.dar   = from->Dar;
407         to->ctl.powerpc_regs.dsisr = from->Dsisr;
408         to->ctl.powerpc_regs.trap  = from->Trap;
409     }
410     if (flags & CONTEXT_INTEGER)
411     {
412         to->flags |= SERVER_CTX_INTEGER;
413         to->integer.powerpc_regs.gpr[0]  = from->Gpr0;
414         to->integer.powerpc_regs.gpr[1]  = from->Gpr1;
415         to->integer.powerpc_regs.gpr[2]  = from->Gpr2;
416         to->integer.powerpc_regs.gpr[3]  = from->Gpr3;
417         to->integer.powerpc_regs.gpr[4]  = from->Gpr4;
418         to->integer.powerpc_regs.gpr[5]  = from->Gpr5;
419         to->integer.powerpc_regs.gpr[6]  = from->Gpr6;
420         to->integer.powerpc_regs.gpr[7]  = from->Gpr7;
421         to->integer.powerpc_regs.gpr[8]  = from->Gpr8;
422         to->integer.powerpc_regs.gpr[9]  = from->Gpr9;
423         to->integer.powerpc_regs.gpr[10] = from->Gpr10;
424         to->integer.powerpc_regs.gpr[11] = from->Gpr11;
425         to->integer.powerpc_regs.gpr[12] = from->Gpr12;
426         to->integer.powerpc_regs.gpr[13] = from->Gpr13;
427         to->integer.powerpc_regs.gpr[14] = from->Gpr14;
428         to->integer.powerpc_regs.gpr[15] = from->Gpr15;
429         to->integer.powerpc_regs.gpr[16] = from->Gpr16;
430         to->integer.powerpc_regs.gpr[17] = from->Gpr17;
431         to->integer.powerpc_regs.gpr[18] = from->Gpr18;
432         to->integer.powerpc_regs.gpr[19] = from->Gpr19;
433         to->integer.powerpc_regs.gpr[20] = from->Gpr20;
434         to->integer.powerpc_regs.gpr[21] = from->Gpr21;
435         to->integer.powerpc_regs.gpr[22] = from->Gpr22;
436         to->integer.powerpc_regs.gpr[23] = from->Gpr23;
437         to->integer.powerpc_regs.gpr[24] = from->Gpr24;
438         to->integer.powerpc_regs.gpr[25] = from->Gpr25;
439         to->integer.powerpc_regs.gpr[26] = from->Gpr26;
440         to->integer.powerpc_regs.gpr[27] = from->Gpr27;
441         to->integer.powerpc_regs.gpr[28] = from->Gpr28;
442         to->integer.powerpc_regs.gpr[29] = from->Gpr29;
443         to->integer.powerpc_regs.gpr[30] = from->Gpr30;
444         to->integer.powerpc_regs.gpr[31] = from->Gpr31;
445         to->integer.powerpc_regs.xer     = from->Xer;
446         to->integer.powerpc_regs.cr      = from->Cr;
447     }
448     if (flags & CONTEXT_FLOATING_POINT)
449     {
450         to->flags |= SERVER_CTX_FLOATING_POINT;
451         to->fp.powerpc_regs.fpr[0]  = from->Fpr0;
452         to->fp.powerpc_regs.fpr[1]  = from->Fpr1;
453         to->fp.powerpc_regs.fpr[2]  = from->Fpr2;
454         to->fp.powerpc_regs.fpr[3]  = from->Fpr3;
455         to->fp.powerpc_regs.fpr[4]  = from->Fpr4;
456         to->fp.powerpc_regs.fpr[5]  = from->Fpr5;
457         to->fp.powerpc_regs.fpr[6]  = from->Fpr6;
458         to->fp.powerpc_regs.fpr[7]  = from->Fpr7;
459         to->fp.powerpc_regs.fpr[8]  = from->Fpr8;
460         to->fp.powerpc_regs.fpr[9]  = from->Fpr9;
461         to->fp.powerpc_regs.fpr[10] = from->Fpr10;
462         to->fp.powerpc_regs.fpr[11] = from->Fpr11;
463         to->fp.powerpc_regs.fpr[12] = from->Fpr12;
464         to->fp.powerpc_regs.fpr[13] = from->Fpr13;
465         to->fp.powerpc_regs.fpr[14] = from->Fpr14;
466         to->fp.powerpc_regs.fpr[15] = from->Fpr15;
467         to->fp.powerpc_regs.fpr[16] = from->Fpr16;
468         to->fp.powerpc_regs.fpr[17] = from->Fpr17;
469         to->fp.powerpc_regs.fpr[18] = from->Fpr18;
470         to->fp.powerpc_regs.fpr[19] = from->Fpr19;
471         to->fp.powerpc_regs.fpr[20] = from->Fpr20;
472         to->fp.powerpc_regs.fpr[21] = from->Fpr21;
473         to->fp.powerpc_regs.fpr[22] = from->Fpr22;
474         to->fp.powerpc_regs.fpr[23] = from->Fpr23;
475         to->fp.powerpc_regs.fpr[24] = from->Fpr24;
476         to->fp.powerpc_regs.fpr[25] = from->Fpr25;
477         to->fp.powerpc_regs.fpr[26] = from->Fpr26;
478         to->fp.powerpc_regs.fpr[27] = from->Fpr27;
479         to->fp.powerpc_regs.fpr[28] = from->Fpr28;
480         to->fp.powerpc_regs.fpr[29] = from->Fpr29;
481         to->fp.powerpc_regs.fpr[30] = from->Fpr30;
482         to->fp.powerpc_regs.fpr[31] = from->Fpr31;
483         to->fp.powerpc_regs.fpscr   = from->Fpscr;
484     }
485     return STATUS_SUCCESS;
486 }
487
488
489 /***********************************************************************
490  *           context_from_server
491  *
492  * Convert a register context from the server format.
493  */
494 NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
495 {
496     if (from->cpu != CPU_POWERPC) return STATUS_INVALID_PARAMETER;
497
498     to->ContextFlags = 0;  /* no CPU id? */
499     if (from->flags & SERVER_CTX_CONTROL)
500     {
501         to->ContextFlags |= CONTEXT_CONTROL;
502         to->Msr   = from->ctl.powerpc_regs.msr;
503         to->Ctr   = from->ctl.powerpc_regs.ctr;
504         to->Iar   = from->ctl.powerpc_regs.iar;
505         to->Lr    = from->ctl.powerpc_regs.lr;
506         to->Dar   = from->ctl.powerpc_regs.dar;
507         to->Dsisr = from->ctl.powerpc_regs.dsisr;
508         to->Trap  = from->ctl.powerpc_regs.trap;
509     }
510     if (from->flags & SERVER_CTX_INTEGER)
511     {
512         to->ContextFlags |= CONTEXT_INTEGER;
513         to->Gpr0  = from->integer.powerpc_regs.gpr[0];
514         to->Gpr1  = from->integer.powerpc_regs.gpr[1];
515         to->Gpr2  = from->integer.powerpc_regs.gpr[2];
516         to->Gpr3  = from->integer.powerpc_regs.gpr[3];
517         to->Gpr4  = from->integer.powerpc_regs.gpr[4];
518         to->Gpr5  = from->integer.powerpc_regs.gpr[5];
519         to->Gpr6  = from->integer.powerpc_regs.gpr[6];
520         to->Gpr7  = from->integer.powerpc_regs.gpr[7];
521         to->Gpr8  = from->integer.powerpc_regs.gpr[8];
522         to->Gpr9  = from->integer.powerpc_regs.gpr[9];
523         to->Gpr10 = from->integer.powerpc_regs.gpr[10];
524         to->Gpr11 = from->integer.powerpc_regs.gpr[11];
525         to->Gpr12 = from->integer.powerpc_regs.gpr[12];
526         to->Gpr13 = from->integer.powerpc_regs.gpr[13];
527         to->Gpr14 = from->integer.powerpc_regs.gpr[14];
528         to->Gpr15 = from->integer.powerpc_regs.gpr[15];
529         to->Gpr16 = from->integer.powerpc_regs.gpr[16];
530         to->Gpr17 = from->integer.powerpc_regs.gpr[17];
531         to->Gpr18 = from->integer.powerpc_regs.gpr[18];
532         to->Gpr19 = from->integer.powerpc_regs.gpr[19];
533         to->Gpr20 = from->integer.powerpc_regs.gpr[20];
534         to->Gpr21 = from->integer.powerpc_regs.gpr[21];
535         to->Gpr22 = from->integer.powerpc_regs.gpr[22];
536         to->Gpr23 = from->integer.powerpc_regs.gpr[23];
537         to->Gpr24 = from->integer.powerpc_regs.gpr[24];
538         to->Gpr25 = from->integer.powerpc_regs.gpr[25];
539         to->Gpr26 = from->integer.powerpc_regs.gpr[26];
540         to->Gpr27 = from->integer.powerpc_regs.gpr[27];
541         to->Gpr28 = from->integer.powerpc_regs.gpr[28];
542         to->Gpr29 = from->integer.powerpc_regs.gpr[29];
543         to->Gpr30 = from->integer.powerpc_regs.gpr[30];
544         to->Gpr31 = from->integer.powerpc_regs.gpr[31];
545         to->Xer   = from->integer.powerpc_regs.xer;
546         to->Cr    = from->integer.powerpc_regs.cr;
547     }
548     if (from->flags & SERVER_CTX_FLOATING_POINT)
549     {
550         to->ContextFlags |= CONTEXT_FLOATING_POINT;
551         to->Fpr0  = from->fp.powerpc_regs.fpr[0];
552         to->Fpr1  = from->fp.powerpc_regs.fpr[1];
553         to->Fpr2  = from->fp.powerpc_regs.fpr[2];
554         to->Fpr3  = from->fp.powerpc_regs.fpr[3];
555         to->Fpr4  = from->fp.powerpc_regs.fpr[4];
556         to->Fpr5  = from->fp.powerpc_regs.fpr[5];
557         to->Fpr6  = from->fp.powerpc_regs.fpr[6];
558         to->Fpr7  = from->fp.powerpc_regs.fpr[7];
559         to->Fpr8  = from->fp.powerpc_regs.fpr[8];
560         to->Fpr9  = from->fp.powerpc_regs.fpr[9];
561         to->Fpr10 = from->fp.powerpc_regs.fpr[10];
562         to->Fpr11 = from->fp.powerpc_regs.fpr[11];
563         to->Fpr12 = from->fp.powerpc_regs.fpr[12];
564         to->Fpr13 = from->fp.powerpc_regs.fpr[13];
565         to->Fpr14 = from->fp.powerpc_regs.fpr[14];
566         to->Fpr15 = from->fp.powerpc_regs.fpr[15];
567         to->Fpr16 = from->fp.powerpc_regs.fpr[16];
568         to->Fpr17 = from->fp.powerpc_regs.fpr[17];
569         to->Fpr18 = from->fp.powerpc_regs.fpr[18];
570         to->Fpr19 = from->fp.powerpc_regs.fpr[19];
571         to->Fpr20 = from->fp.powerpc_regs.fpr[20];
572         to->Fpr21 = from->fp.powerpc_regs.fpr[21];
573         to->Fpr22 = from->fp.powerpc_regs.fpr[22];
574         to->Fpr23 = from->fp.powerpc_regs.fpr[23];
575         to->Fpr24 = from->fp.powerpc_regs.fpr[24];
576         to->Fpr25 = from->fp.powerpc_regs.fpr[25];
577         to->Fpr26 = from->fp.powerpc_regs.fpr[26];
578         to->Fpr27 = from->fp.powerpc_regs.fpr[27];
579         to->Fpr28 = from->fp.powerpc_regs.fpr[28];
580         to->Fpr29 = from->fp.powerpc_regs.fpr[29];
581         to->Fpr30 = from->fp.powerpc_regs.fpr[30];
582         to->Fpr31 = from->fp.powerpc_regs.fpr[31];
583         to->Fpscr = from->fp.powerpc_regs.fpscr;
584     }
585     return STATUS_SUCCESS;
586 }
587
588
589 /**********************************************************************
590  *              get_fpu_code
591  *
592  * Get the FPU exception code from the FPU status.
593  */
594 static inline DWORD get_fpu_code( const CONTEXT *context )
595 {
596     DWORD status  = context->Fpscr;
597
598     if (status & 0x01)  /* IE */
599     {
600         if (status & 0x40)  /* SF */
601             return EXCEPTION_FLT_STACK_CHECK;
602         else
603             return EXCEPTION_FLT_INVALID_OPERATION;
604     }
605     if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND;  /* DE flag */
606     if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO;    /* ZE flag */
607     if (status & 0x08) return EXCEPTION_FLT_OVERFLOW;          /* OE flag */
608     if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW;         /* UE flag */
609     if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT;    /* PE flag */
610     return EXCEPTION_FLT_INVALID_OPERATION;  /* generic error */
611 }
612
613 /**********************************************************************
614  *              do_segv
615  *
616  * Implementation of SIGSEGV handler.
617  */
618 static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr )
619 {
620     EXCEPTION_RECORD rec;
621     NTSTATUS status;
622
623     rec.ExceptionRecord  = NULL;
624     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
625     rec.ExceptionAddress = addr;
626     rec.NumberParameters = 0;
627     
628     switch (trap) {
629     case SIGSEGV:
630         switch ( code & 0xffff ) {
631         case SEGV_MAPERR:
632         case SEGV_ACCERR:
633                 rec.NumberParameters = 2;
634                 rec.ExceptionInformation[0] = 0; /* FIXME ? */
635                 rec.ExceptionInformation[1] = (ULONG_PTR)addr;
636                 if (!(rec.ExceptionCode = virtual_handle_fault(addr, rec.ExceptionInformation[0])))
637                         return;
638                 break;
639         default:FIXME("Unhandled SIGSEGV/%x\n",code);
640                 break;
641         }
642         break;
643     case SIGBUS:
644         switch ( code & 0xffff ) {
645         case BUS_ADRALN:
646                 rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
647                 break;
648 #ifdef BUS_ADRERR
649         case BUS_ADRERR:
650 #endif
651 #ifdef BUS_OBJERR
652         case BUS_OBJERR:
653                 /* FIXME: correct for all cases ? */
654                 rec.NumberParameters = 2;
655                 rec.ExceptionInformation[0] = 0; /* FIXME ? */
656                 rec.ExceptionInformation[1] = (ULONG_PTR)addr;
657                 if (!(rec.ExceptionCode = virtual_handle_fault(addr, rec.ExceptionInformation[0])))
658                         return;
659                 break;
660 #endif
661         default:FIXME("Unhandled SIGBUS/%x\n",code);
662                 break;
663         }
664         break;
665     case SIGILL:
666         switch ( code & 0xffff ) {
667         case ILL_ILLOPC: /* illegal opcode */
668 #ifdef ILL_ILLOPN
669         case ILL_ILLOPN: /* illegal operand */
670 #endif
671 #ifdef ILL_ILLADR
672         case ILL_ILLADR: /* illegal addressing mode */
673 #endif
674 #ifdef ILL_ILLTRP
675         case ILL_ILLTRP: /* illegal trap */
676 #endif
677 #ifdef ILL_COPROC
678         case ILL_COPROC: /* coprocessor error */
679 #endif
680                 rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
681                 break;
682         case ILL_PRVOPC: /* privileged opcode */
683 #ifdef ILL_PRVREG
684         case ILL_PRVREG: /* privileged register */
685 #endif
686                 rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
687                 break;
688 #ifdef ILL_BADSTK
689         case ILL_BADSTK: /* internal stack error */
690                 rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
691                 break;
692 #endif
693         default:FIXME("Unhandled SIGILL/%x\n", code);
694                 break;
695         }
696         break;
697     }
698     status = raise_exception( &rec, context, TRUE );
699     if (status) raise_status( status, &rec );
700 }
701
702 /**********************************************************************
703  *              do_trap
704  *
705  * Implementation of SIGTRAP handler.
706  */
707 static void do_trap( CONTEXT *context, int code, void * addr )
708 {
709     EXCEPTION_RECORD rec;
710     NTSTATUS status;
711
712     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
713     rec.ExceptionRecord  = NULL;
714     rec.ExceptionAddress = addr;
715     rec.NumberParameters = 0;
716
717     /* FIXME: check if we might need to modify PC */
718     switch (code & 0xffff) {
719 #ifdef TRAP_BRKPT
720     case TRAP_BRKPT:
721         rec.ExceptionCode = EXCEPTION_BREAKPOINT;
722         break;
723 #endif
724 #ifdef TRAP_TRACE
725     case TRAP_TRACE:
726         rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
727         break;
728 #endif
729     default:FIXME("Unhandled SIGTRAP/%x\n", code);
730                 break;
731     }
732     status = raise_exception( &rec, context, TRUE );
733     if (status) raise_status( status, &rec );
734 }
735
736 /**********************************************************************
737  *              do_trap
738  *
739  * Implementation of SIGFPE handler.
740  */
741 static void do_fpe( CONTEXT *context, int code, void * addr )
742 {
743     EXCEPTION_RECORD rec;
744     NTSTATUS status;
745
746     switch ( code  & 0xffff ) {
747 #ifdef FPE_FLTSUB
748     case FPE_FLTSUB:
749         rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
750         break;
751 #endif
752 #ifdef FPE_INTDIV
753     case FPE_INTDIV:
754         rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
755         break;
756 #endif
757 #ifdef FPE_INTOVF
758     case FPE_INTOVF:
759         rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
760         break;
761 #endif
762 #ifdef FPE_FLTDIV
763     case FPE_FLTDIV:
764         rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
765         break;
766 #endif
767 #ifdef FPE_FLTOVF
768     case FPE_FLTOVF:
769         rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
770         break;
771 #endif
772 #ifdef FPE_FLTUND
773     case FPE_FLTUND:
774         rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
775         break;
776 #endif
777 #ifdef FPE_FLTRES
778     case FPE_FLTRES:
779         rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
780         break;
781 #endif
782 #ifdef FPE_FLTINV
783     case FPE_FLTINV:
784 #endif
785     default:
786         rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
787         break;
788     }
789     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
790     rec.ExceptionRecord  = NULL;
791     rec.ExceptionAddress = addr;
792     rec.NumberParameters = 0;
793     status = raise_exception( &rec, context, TRUE );
794     if (status) raise_status( status, &rec );
795 }
796
797 /**********************************************************************
798  *              segv_handler
799  *
800  * Handler for SIGSEGV and related errors.
801  */
802 static HANDLER_DEF(segv_handler)
803 {
804     CONTEXT context;
805     save_context( &context, HANDLER_CONTEXT );
806     do_segv( &context, __siginfo->si_signo, __siginfo->si_errno, __siginfo->si_code, __siginfo->si_addr );
807     restore_context( &context, HANDLER_CONTEXT );
808 }
809
810 /**********************************************************************
811  *              trap_handler
812  *
813  * Handler for SIGTRAP.
814  */
815 static HANDLER_DEF(trap_handler)
816 {
817     CONTEXT context;
818     save_context( &context, HANDLER_CONTEXT );
819     do_trap( &context, __siginfo->si_code, __siginfo->si_addr );
820     restore_context( &context, HANDLER_CONTEXT );
821 }
822
823 /**********************************************************************
824  *              fpe_handler
825  *
826  * Handler for SIGFPE.
827  */
828 static HANDLER_DEF(fpe_handler)
829 {
830     CONTEXT context;
831     save_fpu( &context, HANDLER_CONTEXT );
832     save_context( &context, HANDLER_CONTEXT );
833     do_fpe( &context,  __siginfo->si_code, __siginfo->si_addr );
834     restore_context( &context, HANDLER_CONTEXT );
835     restore_fpu( &context, HANDLER_CONTEXT );
836 }
837
838 /**********************************************************************
839  *              int_handler
840  *
841  * Handler for SIGINT.
842  */
843 static HANDLER_DEF(int_handler)
844 {
845     if (!dispatch_signal(SIGINT))
846     {
847         EXCEPTION_RECORD rec;
848         CONTEXT context;
849         NTSTATUS status;
850
851         save_context( &context, HANDLER_CONTEXT );
852         rec.ExceptionCode    = CONTROL_C_EXIT;
853         rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
854         rec.ExceptionRecord  = NULL;
855         rec.ExceptionAddress = (LPVOID)context.Iar;
856         rec.NumberParameters = 0;
857         status = raise_exception( &rec, &context, TRUE );
858         if (status) raise_status( status, &rec );
859         restore_context( &context, HANDLER_CONTEXT );
860     }
861 }
862
863
864 /**********************************************************************
865  *              abrt_handler
866  *
867  * Handler for SIGABRT.
868  */
869 static HANDLER_DEF(abrt_handler)
870 {
871     EXCEPTION_RECORD rec;
872     CONTEXT context;
873     NTSTATUS status;
874
875     save_context( &context, HANDLER_CONTEXT );
876     rec.ExceptionCode    = EXCEPTION_WINE_ASSERTION;
877     rec.ExceptionFlags   = EH_NONCONTINUABLE;
878     rec.ExceptionRecord  = NULL;
879     rec.ExceptionAddress = (LPVOID)context.Iar;
880     rec.NumberParameters = 0;
881     status = raise_exception( &rec, &context, TRUE );
882     if (status) raise_status( status, &rec );
883     restore_context( &context, HANDLER_CONTEXT );
884 }
885
886
887 /**********************************************************************
888  *              quit_handler
889  *
890  * Handler for SIGQUIT.
891  */
892 static HANDLER_DEF(quit_handler)
893 {
894     abort_thread(0);
895 }
896
897
898 /**********************************************************************
899  *              usr1_handler
900  *
901  * Handler for SIGUSR1, used to signal a thread that it got suspended.
902  */
903 static HANDLER_DEF(usr1_handler)
904 {
905     CONTEXT context;
906
907     save_context( &context, HANDLER_CONTEXT );
908     wait_suspend( &context );
909     restore_context( &context, HANDLER_CONTEXT );
910 }
911
912
913 /**********************************************************************
914  *              get_signal_stack_total_size
915  *
916  * Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
917  * Must be a power of two.
918  */
919 size_t get_signal_stack_total_size(void)
920 {
921     assert( sizeof(TEB) <= getpagesize() );
922     return getpagesize();  /* this is just for the TEB, we don't need a signal stack */
923 }
924
925
926 /***********************************************************************
927  *           set_handler
928  *
929  * Set a signal handler
930  */
931 static int set_handler( int sig, void (*func)() )
932 {
933     struct sigaction sig_act;
934
935     sig_act.sa_sigaction = func;
936     sig_act.sa_mask = server_block_set;
937     sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
938     return sigaction( sig, &sig_act, NULL );
939 }
940
941
942 /***********************************************************************
943  *           __wine_set_signal_handler   (NTDLL.@)
944  */
945 int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
946 {
947     if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
948     if (handlers[sig] != NULL) return -2;
949     handlers[sig] = wsh;
950     return 0;
951 }
952
953
954 /**********************************************************************
955  *              signal_init_thread
956  */
957 void signal_init_thread( TEB *teb )
958 {
959     static int init_done;
960
961     if (!init_done)
962     {
963         pthread_key_create( &teb_key, NULL );
964         init_done = 1;
965     }
966     pthread_setspecific( teb_key, teb );
967 }
968
969
970 /**********************************************************************
971  *              signal_init_process
972  */
973 void signal_init_process(void)
974 {
975     if (set_handler( SIGINT,  (void (*)())int_handler ) == -1) goto error;
976     if (set_handler( SIGFPE,  (void (*)())fpe_handler ) == -1) goto error;
977     if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error;
978     if (set_handler( SIGILL,  (void (*)())segv_handler ) == -1) goto error;
979     if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error;
980     if (set_handler( SIGQUIT, (void (*)())quit_handler ) == -1) goto error;
981     if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error;
982 #ifdef SIGBUS
983     if (set_handler( SIGBUS,  (void (*)())segv_handler ) == -1) goto error;
984 #endif
985 #ifdef SIGTRAP
986     if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error;
987 #endif
988     return;
989
990  error:
991     perror("sigaction");
992     exit(1);
993 }
994
995
996 /**********************************************************************
997  *              __wine_enter_vm86   (NTDLL.@)
998  */
999 void __wine_enter_vm86( CONTEXT *context )
1000 {
1001     MESSAGE("vm86 mode not supported on this platform\n");
1002 }
1003
1004 /***********************************************************************
1005  *              RtlRaiseException (NTDLL.@)
1006  */
1007 void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec )
1008 {
1009     CONTEXT context;
1010     NTSTATUS status;
1011
1012     RtlCaptureContext( &context );
1013     rec->ExceptionAddress = (void *)context.Iar;
1014     status = raise_exception( rec, &context, TRUE );
1015     if (status) raise_status( status, rec );
1016 }
1017
1018 /**********************************************************************
1019  *              DbgBreakPoint   (NTDLL.@)
1020  */
1021 void WINAPI DbgBreakPoint(void)
1022 {
1023      kill(getpid(), SIGTRAP);
1024 }
1025
1026 /**********************************************************************
1027  *              DbgUserBreakPoint   (NTDLL.@)
1028  */
1029 void WINAPI DbgUserBreakPoint(void)
1030 {
1031      kill(getpid(), SIGTRAP);
1032 }
1033
1034 /**********************************************************************
1035  *           NtCurrentTeb   (NTDLL.@)
1036  */
1037 TEB * WINAPI NtCurrentTeb(void)
1038 {
1039     return pthread_getspecific( teb_key );
1040 }
1041
1042 #endif  /* __powerpc__ */