credui: Add the Romanian translation.
[wine] / dlls / ntdll / signal_x86_64.c
1 /*
2  * x86-64 signal handling routines
3  *
4  * Copyright 1999, 2005 Alexandre Julliard
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 __x86_64__
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_SYS_SIGNAL_H
39 # include <sys/signal.h>
40 #endif
41
42 #define NONAMELESSUNION
43 #include "windef.h"
44 #include "winternl.h"
45 #include "wine/library.h"
46 #include "wine/exception.h"
47 #include "ntdll_misc.h"
48 #include "wine/debug.h"
49
50 WINE_DEFAULT_DEBUG_CHANNEL(seh);
51
52
53 /***********************************************************************
54  * signal context platform-specific definitions
55  */
56 #ifdef linux
57
58 #include <asm/prctl.h>
59 extern int arch_prctl(int func, void *ptr);
60
61 typedef struct ucontext SIGCONTEXT;
62
63 # define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
64 # define HANDLER_CONTEXT (__context)
65
66 #define RAX_sig(context)     ((context)->uc_mcontext.gregs[REG_RAX])
67 #define RBX_sig(context)     ((context)->uc_mcontext.gregs[REG_RBX])
68 #define RCX_sig(context)     ((context)->uc_mcontext.gregs[REG_RCX])
69 #define RDX_sig(context)     ((context)->uc_mcontext.gregs[REG_RDX])
70 #define RSI_sig(context)     ((context)->uc_mcontext.gregs[REG_RSI])
71 #define RDI_sig(context)     ((context)->uc_mcontext.gregs[REG_RDI])
72 #define RBP_sig(context)     ((context)->uc_mcontext.gregs[REG_RBP])
73 #define R8_sig(context)      ((context)->uc_mcontext.gregs[REG_R8])
74 #define R9_sig(context)      ((context)->uc_mcontext.gregs[REG_R9])
75 #define R10_sig(context)     ((context)->uc_mcontext.gregs[REG_R10])
76 #define R11_sig(context)     ((context)->uc_mcontext.gregs[REG_R11])
77 #define R12_sig(context)     ((context)->uc_mcontext.gregs[REG_R12])
78 #define R13_sig(context)     ((context)->uc_mcontext.gregs[REG_R13])
79 #define R14_sig(context)     ((context)->uc_mcontext.gregs[REG_R14])
80 #define R15_sig(context)     ((context)->uc_mcontext.gregs[REG_R15])
81
82 #define CS_sig(context)      (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 0))
83 #define GS_sig(context)      (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 1))
84 #define FS_sig(context)      (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 2))
85
86 #define RSP_sig(context)     ((context)->uc_mcontext.gregs[REG_RSP])
87 #define RIP_sig(context)     ((context)->uc_mcontext.gregs[REG_RIP])
88 #define EFL_sig(context)     ((context)->uc_mcontext.gregs[REG_EFL])
89 #define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
90 #define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
91
92 #define FPU_sig(context)     ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.fpregs))
93
94 #define FAULT_CODE     (__siginfo->si_code)
95 #define FAULT_ADDRESS  (__siginfo->si_addr)
96
97 #endif /* linux */
98
99 #if defined(__NetBSD__)
100 # include <sys/ucontext.h>
101 # include <sys/types.h>
102 # include <signal.h>
103
104 typedef ucontext_t SIGCONTEXT;
105
106 #define RAX_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RAX])
107 #define RBX_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RBX])
108 #define RCX_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RCX])
109 #define RDX_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RDX])
110 #define RSI_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RSI])
111 #define RDI_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RDI])
112 #define RBP_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RBP])
113 #define R8_sig(context)     ((context)->uc_mcontext.__gregs[_REG_R8])
114 #define R9_sig(context)     ((context)->uc_mcontext.__gregs[_REG_R9])
115 #define R10_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R10])
116 #define R11_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R11])
117 #define R12_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R12])
118 #define R13_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R13])
119 #define R14_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R14])
120 #define R15_sig(context)    ((context)->uc_mcontext.__gregs[_REG_R15])
121
122 #define CS_sig(context)     ((context)->uc_mcontext.__gregs[_REG_CS])
123 #define DS_sig(context)     ((context)->uc_mcontext.__gregs[_REG_DS])
124 #define ES_sig(context)     ((context)->uc_mcontext.__gregs[_REG_ES])
125 #define FS_sig(context)     ((context)->uc_mcontext.__gregs[_REG_FS])
126 #define GS_sig(context)     ((context)->uc_mcontext.__gregs[_REG_GS])
127 #define SS_sig(context)     ((context)->uc_mcontext.__gregs[_REG_SS])
128
129 #define EFL_sig(context)    ((context)->uc_mcontext.__gregs[_REG_RFL])
130
131 #define RIP_sig(context)    (*((unsigned long*)&(context)->uc_mcontext.__gregs[_REG_RIP]))
132 #define RSP_sig(context)    (*((unsigned long*)&(context)->uc_mcontext.__gregs[_REG_URSP]))
133
134 #define TRAP_sig(context)   ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
135 #define ERROR_sig(context)  ((context)->uc_mcontext.__gregs[_REG_ERR])
136
137 #define FAULT_CODE          (__siginfo->si_code)
138 #define FAULT_ADDRESS       (__siginfo->si_addr)
139
140 #define HANDLER_DEF(name) void name( int __signal, siginfo_t *__siginfo, SIGCONTEXT *__context )
141 #define HANDLER_CONTEXT (__context)
142
143 #define FPU_sig(context)   ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs))
144 #endif /* __NetBSD__ */
145
146 enum i386_trap_code
147 {
148     TRAP_x86_UNKNOWN    = -1,  /* Unknown fault (TRAP_sig not defined) */
149     TRAP_x86_DIVIDE     = 0,   /* Division by zero exception */
150     TRAP_x86_TRCTRAP    = 1,   /* Single-step exception */
151     TRAP_x86_NMI        = 2,   /* NMI interrupt */
152     TRAP_x86_BPTFLT     = 3,   /* Breakpoint exception */
153     TRAP_x86_OFLOW      = 4,   /* Overflow exception */
154     TRAP_x86_BOUND      = 5,   /* Bound range exception */
155     TRAP_x86_PRIVINFLT  = 6,   /* Invalid opcode exception */
156     TRAP_x86_DNA        = 7,   /* Device not available exception */
157     TRAP_x86_DOUBLEFLT  = 8,   /* Double fault exception */
158     TRAP_x86_FPOPFLT    = 9,   /* Coprocessor segment overrun */
159     TRAP_x86_TSSFLT     = 10,  /* Invalid TSS exception */
160     TRAP_x86_SEGNPFLT   = 11,  /* Segment not present exception */
161     TRAP_x86_STKFLT     = 12,  /* Stack fault */
162     TRAP_x86_PROTFLT    = 13,  /* General protection fault */
163     TRAP_x86_PAGEFLT    = 14,  /* Page fault */
164     TRAP_x86_ARITHTRAP  = 16,  /* Floating point exception */
165     TRAP_x86_ALIGNFLT   = 17,  /* Alignment check exception */
166     TRAP_x86_MCHK       = 18,  /* Machine check exception */
167     TRAP_x86_CACHEFLT   = 19   /* Cache flush exception */
168 };
169
170 typedef int (*wine_signal_handler)(unsigned int sig);
171
172 static wine_signal_handler handlers[256];
173
174 /***********************************************************************
175  *           dispatch_signal
176  */
177 static inline int dispatch_signal(unsigned int sig)
178 {
179     if (handlers[sig] == NULL) return 0;
180     return handlers[sig](sig);
181 }
182
183 /***********************************************************************
184  *           save_context
185  *
186  * Set the register values from a sigcontext.
187  */
188 static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
189 {
190     context->Rax    = RAX_sig(sigcontext);
191     context->Rcx    = RCX_sig(sigcontext);
192     context->Rdx    = RDX_sig(sigcontext);
193     context->Rbx    = RBX_sig(sigcontext);
194     context->Rsp    = RSP_sig(sigcontext);
195     context->Rbp    = RBP_sig(sigcontext);
196     context->Rsi    = RSI_sig(sigcontext);
197     context->Rdi    = RDI_sig(sigcontext);
198     context->R8     = R8_sig(sigcontext);
199     context->R9     = R9_sig(sigcontext);
200     context->R10    = R10_sig(sigcontext);
201     context->R11    = R11_sig(sigcontext);
202     context->R12    = R12_sig(sigcontext);
203     context->R13    = R13_sig(sigcontext);
204     context->R14    = R14_sig(sigcontext);
205     context->R15    = R15_sig(sigcontext);
206     context->Rip    = RIP_sig(sigcontext);
207     context->SegCs  = CS_sig(sigcontext);
208     context->SegFs  = FS_sig(sigcontext);
209     context->SegGs  = GS_sig(sigcontext);
210     context->EFlags = EFL_sig(sigcontext);
211     context->SegDs  = 0;  /* FIXME */
212     context->SegEs  = 0;  /* FIXME */
213     context->SegSs  = 0;  /* FIXME */
214     context->MxCsr  = 0;  /* FIXME */
215     if (FPU_sig(sigcontext)) context->u.FltSave = *FPU_sig(sigcontext);
216 }
217
218
219 /***********************************************************************
220  *           restore_context
221  *
222  * Build a sigcontext from the register values.
223  */
224 static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
225 {
226     RAX_sig(sigcontext) = context->Rax;
227     RCX_sig(sigcontext) = context->Rcx;
228     RDX_sig(sigcontext) = context->Rdx;
229     RBX_sig(sigcontext) = context->Rbx;
230     RSP_sig(sigcontext) = context->Rsp;
231     RBP_sig(sigcontext) = context->Rbp;
232     RSI_sig(sigcontext) = context->Rsi;
233     RDI_sig(sigcontext) = context->Rdi;
234     R8_sig(sigcontext)  = context->R8;
235     R9_sig(sigcontext)  = context->R9;
236     R10_sig(sigcontext) = context->R10;
237     R11_sig(sigcontext) = context->R11;
238     R12_sig(sigcontext) = context->R12;
239     R13_sig(sigcontext) = context->R13;
240     R14_sig(sigcontext) = context->R14;
241     R15_sig(sigcontext) = context->R15;
242     RIP_sig(sigcontext) = context->Rip;
243     CS_sig(sigcontext)  = context->SegCs;
244     FS_sig(sigcontext)  = context->SegFs;
245     GS_sig(sigcontext)  = context->SegGs;
246     EFL_sig(sigcontext) = context->EFlags;
247     if (FPU_sig(sigcontext)) *FPU_sig(sigcontext) = context->u.FltSave;
248 }
249
250
251 /***********************************************************************
252  *              RtlCaptureContext (NTDLL.@)
253  */
254 void WINAPI __regs_RtlCaptureContext( CONTEXT *context, CONTEXT *regs )
255 {
256     *context = *regs;
257 }
258 DEFINE_REGS_ENTRYPOINT( RtlCaptureContext, 1 )
259
260
261 /***********************************************************************
262  *           set_cpu_context
263  *
264  * Set the new CPU context.
265  */
266 void set_cpu_context( const CONTEXT *context )
267 {
268     FIXME("not implemented\n");
269 }
270
271
272 /***********************************************************************
273  *           copy_context
274  *
275  * Copy a register context according to the flags.
276  */
277 void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
278 {
279     flags &= ~CONTEXT_AMD64;  /* get rid of CPU id */
280     if (flags & CONTEXT_CONTROL)
281     {
282         to->Rbp    = from->Rbp;
283         to->Rip    = from->Rip;
284         to->Rsp    = from->Rsp;
285         to->SegCs  = from->SegCs;
286         to->SegSs  = from->SegSs;
287         to->EFlags = from->EFlags;
288         to->MxCsr  = from->MxCsr;
289     }
290     if (flags & CONTEXT_INTEGER)
291     {
292         to->Rax = from->Rax;
293         to->Rcx = from->Rcx;
294         to->Rdx = from->Rdx;
295         to->Rbx = from->Rbx;
296         to->Rsi = from->Rsi;
297         to->Rdi = from->Rdi;
298         to->R8  = from->R8;
299         to->R9  = from->R9;
300         to->R10 = from->R10;
301         to->R11 = from->R11;
302         to->R12 = from->R12;
303         to->R13 = from->R13;
304         to->R14 = from->R14;
305         to->R15 = from->R15;
306     }
307     if (flags & CONTEXT_SEGMENTS)
308     {
309         to->SegDs = from->SegDs;
310         to->SegEs = from->SegEs;
311         to->SegFs = from->SegFs;
312         to->SegGs = from->SegGs;
313     }
314     if (flags & CONTEXT_FLOATING_POINT)
315     {
316         to->u.FltSave = from->u.FltSave;
317     }
318     if (flags & CONTEXT_DEBUG_REGISTERS)
319     {
320         to->Dr0 = from->Dr0;
321         to->Dr1 = from->Dr1;
322         to->Dr2 = from->Dr2;
323         to->Dr3 = from->Dr3;
324         to->Dr6 = from->Dr6;
325         to->Dr7 = from->Dr7;
326     }
327 }
328
329
330 /**********************************************************************
331  *              segv_handler
332  *
333  * Handler for SIGSEGV and related errors.
334  */
335 static HANDLER_DEF(segv_handler)
336 {
337     EXCEPTION_RECORD rec;
338     CONTEXT context;
339
340     save_context( &context, HANDLER_CONTEXT );
341
342     rec.ExceptionRecord  = NULL;
343     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
344     rec.ExceptionAddress = (LPVOID)context.Rip;
345     rec.NumberParameters = 0;
346
347     switch(TRAP_sig(HANDLER_CONTEXT))
348     {
349     case TRAP_x86_OFLOW:   /* Overflow exception */
350         rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
351         break;
352     case TRAP_x86_BOUND:   /* Bound range exception */
353         rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
354         break;
355     case TRAP_x86_PRIVINFLT:   /* Invalid opcode exception */
356         rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
357         break;
358     case TRAP_x86_STKFLT:  /* Stack fault */
359         rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
360         break;
361     case TRAP_x86_SEGNPFLT:  /* Segment not present exception */
362     case TRAP_x86_PROTFLT:   /* General protection fault */
363     case TRAP_x86_UNKNOWN:   /* Unknown fault code */
364         rec.ExceptionCode = ERROR_sig(HANDLER_CONTEXT) ? EXCEPTION_ACCESS_VIOLATION
365                                                        : EXCEPTION_PRIV_INSTRUCTION;
366         break;
367     case TRAP_x86_PAGEFLT:  /* Page fault */
368         rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
369 #ifdef FAULT_ADDRESS
370         rec.NumberParameters = 2;
371         rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0;
372         rec.ExceptionInformation[1] = (ULONG_PTR)FAULT_ADDRESS;
373         if (!(rec.ExceptionCode = virtual_handle_fault( FAULT_ADDRESS, rec.ExceptionInformation[0] )))
374             goto done;
375 #endif
376         break;
377     case TRAP_x86_ALIGNFLT:  /* Alignment check exception */
378         rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
379         break;
380     default:
381         ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
382         /* fall through */
383     case TRAP_x86_NMI:       /* NMI interrupt */
384     case TRAP_x86_DNA:       /* Device not available exception */
385     case TRAP_x86_DOUBLEFLT: /* Double fault exception */
386     case TRAP_x86_TSSFLT:    /* Invalid TSS exception */
387     case TRAP_x86_MCHK:      /* Machine check exception */
388     case TRAP_x86_CACHEFLT:  /* Cache flush exception */
389         rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
390         break;
391     }
392
393     __regs_RtlRaiseException( &rec, &context );
394 done:
395     restore_context( &context, HANDLER_CONTEXT );
396 }
397
398 /**********************************************************************
399  *              trap_handler
400  *
401  * Handler for SIGTRAP.
402  */
403 static HANDLER_DEF(trap_handler)
404 {
405     EXCEPTION_RECORD rec;
406     CONTEXT context;
407
408     save_context( &context, HANDLER_CONTEXT );
409     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
410     rec.ExceptionRecord  = NULL;
411     rec.ExceptionAddress = (LPVOID)context.Rip;
412     rec.NumberParameters = 0;
413
414     switch(FAULT_CODE)
415     {
416     case TRAP_TRACE:  /* Single-step exception */
417         rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
418         EFL_sig(HANDLER_CONTEXT) &= ~0x100;  /* clear single-step flag */
419         break;
420     case TRAP_BRKPT:   /* Breakpoint exception */
421         rec.ExceptionAddress = (char *)rec.ExceptionAddress - 1;  /* back up over the int3 instruction */
422         /* fall through */
423     default:
424         rec.ExceptionCode = EXCEPTION_BREAKPOINT;
425         break;
426     }
427
428     __regs_RtlRaiseException( &rec, &context );
429     restore_context( &context, HANDLER_CONTEXT );
430 }
431
432 /**********************************************************************
433  *              fpe_handler
434  *
435  * Handler for SIGFPE.
436  */
437 static HANDLER_DEF(fpe_handler)
438 {
439     EXCEPTION_RECORD rec;
440     CONTEXT context;
441
442     save_context( &context, HANDLER_CONTEXT );
443     rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
444     rec.ExceptionRecord  = NULL;
445     rec.ExceptionAddress = (LPVOID)context.Rip;
446     rec.NumberParameters = 0;
447
448     switch (FAULT_CODE)
449     {
450     case FPE_FLTSUB:
451         rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
452         break;
453     case FPE_INTDIV:
454         rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
455         break;
456     case FPE_INTOVF:
457         rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
458         break;
459     case FPE_FLTDIV:
460         rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
461         break;
462     case FPE_FLTOVF:
463         rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
464         break;
465     case FPE_FLTUND:
466         rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
467         break;
468     case FPE_FLTRES:
469         rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
470         break;
471     case FPE_FLTINV:
472     default:
473         rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
474         break;
475     }
476
477     __regs_RtlRaiseException( &rec, &context );
478     restore_context( &context, HANDLER_CONTEXT );
479 }
480
481 /**********************************************************************
482  *              int_handler
483  *
484  * Handler for SIGINT.
485  */
486 static HANDLER_DEF(int_handler)
487 {
488     if (!dispatch_signal(SIGINT))
489     {
490         EXCEPTION_RECORD rec;
491         CONTEXT context;
492
493         save_context( &context, HANDLER_CONTEXT );
494         rec.ExceptionCode    = CONTROL_C_EXIT;
495         rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
496         rec.ExceptionRecord  = NULL;
497         rec.ExceptionAddress = (LPVOID)context.Rip;
498         rec.NumberParameters = 0;
499         __regs_RtlRaiseException( &rec, &context );
500         restore_context( &context, HANDLER_CONTEXT );
501     }
502 }
503
504
505 /**********************************************************************
506  *              abrt_handler
507  *
508  * Handler for SIGABRT.
509  */
510 static HANDLER_DEF(abrt_handler)
511 {
512     EXCEPTION_RECORD rec;
513     CONTEXT context;
514
515     save_context( &context, HANDLER_CONTEXT );
516     rec.ExceptionCode    = EXCEPTION_WINE_ASSERTION;
517     rec.ExceptionFlags   = EH_NONCONTINUABLE;
518     rec.ExceptionRecord  = NULL;
519     rec.ExceptionAddress = (LPVOID)context.Rip;
520     rec.NumberParameters = 0;
521     __regs_RtlRaiseException( &rec, &context ); /* Should never return.. */
522     restore_context( &context, HANDLER_CONTEXT );
523 }
524
525
526 /**********************************************************************
527  *              quit_handler
528  *
529  * Handler for SIGQUIT.
530  */
531 static HANDLER_DEF(quit_handler)
532 {
533     abort_thread(0);
534 }
535
536
537 /**********************************************************************
538  *              usr1_handler
539  *
540  * Handler for SIGUSR1, used to signal a thread that it got suspended.
541  */
542 static HANDLER_DEF(usr1_handler)
543 {
544     CONTEXT context;
545
546     save_context( &context, HANDLER_CONTEXT );
547     wait_suspend( &context );
548     restore_context( &context, HANDLER_CONTEXT );
549 }
550
551
552 /**********************************************************************
553  *              get_signal_stack_total_size
554  *
555  * Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
556  * Must be a power of two.
557  */
558 size_t get_signal_stack_total_size(void)
559 {
560     assert( sizeof(TEB) <= 2*getpagesize() );
561     return 2*getpagesize();  /* this is just for the TEB, we don't need a signal stack */
562 }
563
564
565 /***********************************************************************
566  *           set_handler
567  *
568  * Set a signal handler
569  */
570 static int set_handler( int sig, void (*func)() )
571 {
572     struct sigaction sig_act;
573
574     sig_act.sa_sigaction = func;
575     sig_act.sa_mask = server_block_set;
576     sig_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
577     return sigaction( sig, &sig_act, NULL );
578 }
579
580
581 /***********************************************************************
582  *           __wine_set_signal_handler   (NTDLL.@)
583  */
584 int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
585 {
586     if (sig > sizeof(handlers) / sizeof(handlers[0])) return -1;
587     if (handlers[sig] != NULL) return -2;
588     handlers[sig] = wsh;
589     return 0;
590 }
591
592
593 /**********************************************************************
594  *              signal_init_thread
595  */
596 void signal_init_thread( TEB *teb )
597 {
598 #ifdef __linux__
599     arch_prctl( ARCH_SET_GS, teb );
600 #else
601 # error Please define setting %gs for your architecture
602 #endif
603 }
604
605 /**********************************************************************
606  *              signal_init_process
607  */
608 void signal_init_process(void)
609 {
610     if (set_handler( SIGINT,  (void (*)())int_handler ) == -1) goto error;
611     if (set_handler( SIGFPE,  (void (*)())fpe_handler ) == -1) goto error;
612     if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error;
613     if (set_handler( SIGILL,  (void (*)())segv_handler ) == -1) goto error;
614     if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error;
615     if (set_handler( SIGQUIT, (void (*)())quit_handler ) == -1) goto error;
616     if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error;
617 #ifdef SIGBUS
618     if (set_handler( SIGBUS,  (void (*)())segv_handler ) == -1) goto error;
619 #endif
620 #ifdef SIGTRAP
621     if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error;
622 #endif
623     return;
624
625  error:
626     perror("sigaction");
627     exit(1);
628 }
629
630
631 /**********************************************************************
632  *              RtlLookupFunctionEntry   (NTDLL.@)
633  */
634 PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry( ULONG64 pc, ULONG64 *base,
635                                                  UNWIND_HISTORY_TABLE *table )
636 {
637     FIXME("stub\n");
638     return NULL;
639 }
640
641
642 /**********************************************************************
643  *              RtlVirtualUnwind   (NTDLL.@)
644  */
645 PVOID WINAPI RtlVirtualUnwind ( ULONG type, ULONG64 base, ULONG64 pc,
646                                 RUNTIME_FUNCTION *function, CONTEXT *context,
647                                 PVOID *data, ULONG64 *frame,
648                                 KNONVOLATILE_CONTEXT_POINTERS *ctx_ptr )
649 {
650     FIXME("stub\n");
651     return NULL;
652 }
653
654
655 /**********************************************************************
656  *              __wine_enter_vm86   (NTDLL.@)
657  */
658 void __wine_enter_vm86( CONTEXT *context )
659 {
660     MESSAGE("vm86 mode not supported on this platform\n");
661 }
662
663 /**********************************************************************
664  *              DbgBreakPoint   (NTDLL.@)
665  */
666 __ASM_GLOBAL_FUNC( DbgBreakPoint, "int $3; ret")
667
668 /**********************************************************************
669  *              DbgUserBreakPoint   (NTDLL.@)
670  */
671 __ASM_GLOBAL_FUNC( DbgUserBreakPoint, "int $3; ret")
672
673 #endif  /* __x86_64__ */