2 * x86-64 signal handling routines
4 * Copyright 1999, 2005 Alexandre Julliard
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.
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.
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
24 #include "wine/port.h"
35 #ifdef HAVE_SYS_PARAM_H
36 # include <sys/param.h>
38 #ifdef HAVE_SYS_SIGNAL_H
39 # include <sys/signal.h>
42 #define NONAMELESSUNION
44 #define WIN32_NO_STATUS
47 #include "wine/library.h"
48 #include "wine/exception.h"
49 #include "ntdll_misc.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(seh
);
55 /***********************************************************************
56 * signal context platform-specific definitions
60 #include <asm/prctl.h>
61 extern int arch_prctl(int func
, void *ptr
);
63 typedef struct ucontext SIGCONTEXT
;
65 # define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
66 # define HANDLER_CONTEXT (__context)
68 #define RAX_sig(context) ((context)->uc_mcontext.gregs[REG_RAX])
69 #define RBX_sig(context) ((context)->uc_mcontext.gregs[REG_RBX])
70 #define RCX_sig(context) ((context)->uc_mcontext.gregs[REG_RCX])
71 #define RDX_sig(context) ((context)->uc_mcontext.gregs[REG_RDX])
72 #define RSI_sig(context) ((context)->uc_mcontext.gregs[REG_RSI])
73 #define RDI_sig(context) ((context)->uc_mcontext.gregs[REG_RDI])
74 #define RBP_sig(context) ((context)->uc_mcontext.gregs[REG_RBP])
75 #define R8_sig(context) ((context)->uc_mcontext.gregs[REG_R8])
76 #define R9_sig(context) ((context)->uc_mcontext.gregs[REG_R9])
77 #define R10_sig(context) ((context)->uc_mcontext.gregs[REG_R10])
78 #define R11_sig(context) ((context)->uc_mcontext.gregs[REG_R11])
79 #define R12_sig(context) ((context)->uc_mcontext.gregs[REG_R12])
80 #define R13_sig(context) ((context)->uc_mcontext.gregs[REG_R13])
81 #define R14_sig(context) ((context)->uc_mcontext.gregs[REG_R14])
82 #define R15_sig(context) ((context)->uc_mcontext.gregs[REG_R15])
84 #define CS_sig(context) (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 0))
85 #define GS_sig(context) (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 1))
86 #define FS_sig(context) (*((WORD *)&(context)->uc_mcontext.gregs[REG_CSGSFS] + 2))
88 #define RSP_sig(context) ((context)->uc_mcontext.gregs[REG_RSP])
89 #define RIP_sig(context) ((context)->uc_mcontext.gregs[REG_RIP])
90 #define EFL_sig(context) ((context)->uc_mcontext.gregs[REG_EFL])
91 #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
92 #define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
94 #define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.fpregs))
96 #define FAULT_CODE (__siginfo->si_code)
97 #define FAULT_ADDRESS (__siginfo->si_addr)
101 #if defined(__NetBSD__)
102 # include <sys/ucontext.h>
103 # include <sys/types.h>
106 typedef ucontext_t SIGCONTEXT
;
108 #define RAX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RAX])
109 #define RBX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RBX])
110 #define RCX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RCX])
111 #define RDX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RDX])
112 #define RSI_sig(context) ((context)->uc_mcontext.__gregs[_REG_RSI])
113 #define RDI_sig(context) ((context)->uc_mcontext.__gregs[_REG_RDI])
114 #define RBP_sig(context) ((context)->uc_mcontext.__gregs[_REG_RBP])
115 #define R8_sig(context) ((context)->uc_mcontext.__gregs[_REG_R8])
116 #define R9_sig(context) ((context)->uc_mcontext.__gregs[_REG_R9])
117 #define R10_sig(context) ((context)->uc_mcontext.__gregs[_REG_R10])
118 #define R11_sig(context) ((context)->uc_mcontext.__gregs[_REG_R11])
119 #define R12_sig(context) ((context)->uc_mcontext.__gregs[_REG_R12])
120 #define R13_sig(context) ((context)->uc_mcontext.__gregs[_REG_R13])
121 #define R14_sig(context) ((context)->uc_mcontext.__gregs[_REG_R14])
122 #define R15_sig(context) ((context)->uc_mcontext.__gregs[_REG_R15])
124 #define CS_sig(context) ((context)->uc_mcontext.__gregs[_REG_CS])
125 #define DS_sig(context) ((context)->uc_mcontext.__gregs[_REG_DS])
126 #define ES_sig(context) ((context)->uc_mcontext.__gregs[_REG_ES])
127 #define FS_sig(context) ((context)->uc_mcontext.__gregs[_REG_FS])
128 #define GS_sig(context) ((context)->uc_mcontext.__gregs[_REG_GS])
129 #define SS_sig(context) ((context)->uc_mcontext.__gregs[_REG_SS])
131 #define EFL_sig(context) ((context)->uc_mcontext.__gregs[_REG_RFL])
133 #define RIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.__gregs[_REG_RIP]))
134 #define RSP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.__gregs[_REG_URSP]))
136 #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
137 #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
139 #define FAULT_CODE (__siginfo->si_code)
140 #define FAULT_ADDRESS (__siginfo->si_addr)
142 #define HANDLER_DEF(name) void name( int __signal, siginfo_t *__siginfo, SIGCONTEXT *__context )
143 #define HANDLER_CONTEXT (__context)
145 #define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs))
146 #endif /* __NetBSD__ */
150 TRAP_x86_UNKNOWN
= -1, /* Unknown fault (TRAP_sig not defined) */
151 TRAP_x86_DIVIDE
= 0, /* Division by zero exception */
152 TRAP_x86_TRCTRAP
= 1, /* Single-step exception */
153 TRAP_x86_NMI
= 2, /* NMI interrupt */
154 TRAP_x86_BPTFLT
= 3, /* Breakpoint exception */
155 TRAP_x86_OFLOW
= 4, /* Overflow exception */
156 TRAP_x86_BOUND
= 5, /* Bound range exception */
157 TRAP_x86_PRIVINFLT
= 6, /* Invalid opcode exception */
158 TRAP_x86_DNA
= 7, /* Device not available exception */
159 TRAP_x86_DOUBLEFLT
= 8, /* Double fault exception */
160 TRAP_x86_FPOPFLT
= 9, /* Coprocessor segment overrun */
161 TRAP_x86_TSSFLT
= 10, /* Invalid TSS exception */
162 TRAP_x86_SEGNPFLT
= 11, /* Segment not present exception */
163 TRAP_x86_STKFLT
= 12, /* Stack fault */
164 TRAP_x86_PROTFLT
= 13, /* General protection fault */
165 TRAP_x86_PAGEFLT
= 14, /* Page fault */
166 TRAP_x86_ARITHTRAP
= 16, /* Floating point exception */
167 TRAP_x86_ALIGNFLT
= 17, /* Alignment check exception */
168 TRAP_x86_MCHK
= 18, /* Machine check exception */
169 TRAP_x86_CACHEFLT
= 19 /* Cache flush exception */
172 typedef int (*wine_signal_handler
)(unsigned int sig
);
174 static wine_signal_handler handlers
[256];
176 /***********************************************************************
179 static inline int dispatch_signal(unsigned int sig
)
181 if (handlers
[sig
] == NULL
) return 0;
182 return handlers
[sig
](sig
);
185 /***********************************************************************
188 * Set the register values from a sigcontext.
190 static void save_context( CONTEXT
*context
, const SIGCONTEXT
*sigcontext
)
192 context
->ContextFlags
= CONTEXT_CONTROL
| CONTEXT_INTEGER
| CONTEXT_SEGMENTS
;
193 context
->Rax
= RAX_sig(sigcontext
);
194 context
->Rcx
= RCX_sig(sigcontext
);
195 context
->Rdx
= RDX_sig(sigcontext
);
196 context
->Rbx
= RBX_sig(sigcontext
);
197 context
->Rsp
= RSP_sig(sigcontext
);
198 context
->Rbp
= RBP_sig(sigcontext
);
199 context
->Rsi
= RSI_sig(sigcontext
);
200 context
->Rdi
= RDI_sig(sigcontext
);
201 context
->R8
= R8_sig(sigcontext
);
202 context
->R9
= R9_sig(sigcontext
);
203 context
->R10
= R10_sig(sigcontext
);
204 context
->R11
= R11_sig(sigcontext
);
205 context
->R12
= R12_sig(sigcontext
);
206 context
->R13
= R13_sig(sigcontext
);
207 context
->R14
= R14_sig(sigcontext
);
208 context
->R15
= R15_sig(sigcontext
);
209 context
->Rip
= RIP_sig(sigcontext
);
210 context
->SegCs
= CS_sig(sigcontext
);
211 context
->SegFs
= FS_sig(sigcontext
);
212 context
->SegGs
= GS_sig(sigcontext
);
213 context
->EFlags
= EFL_sig(sigcontext
);
214 context
->SegDs
= 0; /* FIXME */
215 context
->SegEs
= 0; /* FIXME */
216 context
->SegSs
= 0; /* FIXME */
217 context
->MxCsr
= 0; /* FIXME */
218 if (FPU_sig(sigcontext
))
220 context
->ContextFlags
|= CONTEXT_FLOATING_POINT
;
221 context
->u
.FltSave
= *FPU_sig(sigcontext
);
226 /***********************************************************************
229 * Build a sigcontext from the register values.
231 static void restore_context( const CONTEXT
*context
, SIGCONTEXT
*sigcontext
)
233 RAX_sig(sigcontext
) = context
->Rax
;
234 RCX_sig(sigcontext
) = context
->Rcx
;
235 RDX_sig(sigcontext
) = context
->Rdx
;
236 RBX_sig(sigcontext
) = context
->Rbx
;
237 RSP_sig(sigcontext
) = context
->Rsp
;
238 RBP_sig(sigcontext
) = context
->Rbp
;
239 RSI_sig(sigcontext
) = context
->Rsi
;
240 RDI_sig(sigcontext
) = context
->Rdi
;
241 R8_sig(sigcontext
) = context
->R8
;
242 R9_sig(sigcontext
) = context
->R9
;
243 R10_sig(sigcontext
) = context
->R10
;
244 R11_sig(sigcontext
) = context
->R11
;
245 R12_sig(sigcontext
) = context
->R12
;
246 R13_sig(sigcontext
) = context
->R13
;
247 R14_sig(sigcontext
) = context
->R14
;
248 R15_sig(sigcontext
) = context
->R15
;
249 RIP_sig(sigcontext
) = context
->Rip
;
250 CS_sig(sigcontext
) = context
->SegCs
;
251 FS_sig(sigcontext
) = context
->SegFs
;
252 GS_sig(sigcontext
) = context
->SegGs
;
253 EFL_sig(sigcontext
) = context
->EFlags
;
254 if (FPU_sig(sigcontext
)) *FPU_sig(sigcontext
) = context
->u
.FltSave
;
258 /***********************************************************************
259 * RtlCaptureContext (NTDLL.@)
261 void WINAPI
__regs_RtlCaptureContext( CONTEXT
*context
, CONTEXT
*regs
)
265 DEFINE_REGS_ENTRYPOINT( RtlCaptureContext
, 1 )
268 /***********************************************************************
271 * Set the new CPU context.
273 void set_cpu_context( const CONTEXT
*context
)
275 FIXME("not implemented\n");
279 /***********************************************************************
282 * Copy a register context according to the flags.
284 void copy_context( CONTEXT
*to
, const CONTEXT
*from
, DWORD flags
)
286 flags
&= ~CONTEXT_AMD64
; /* get rid of CPU id */
287 if (flags
& CONTEXT_CONTROL
)
292 to
->SegCs
= from
->SegCs
;
293 to
->SegSs
= from
->SegSs
;
294 to
->EFlags
= from
->EFlags
;
295 to
->MxCsr
= from
->MxCsr
;
297 if (flags
& CONTEXT_INTEGER
)
314 if (flags
& CONTEXT_SEGMENTS
)
316 to
->SegDs
= from
->SegDs
;
317 to
->SegEs
= from
->SegEs
;
318 to
->SegFs
= from
->SegFs
;
319 to
->SegGs
= from
->SegGs
;
321 if (flags
& CONTEXT_FLOATING_POINT
)
323 to
->u
.FltSave
= from
->u
.FltSave
;
325 if (flags
& CONTEXT_DEBUG_REGISTERS
)
337 /***********************************************************************
340 * Convert a register context to the server format.
342 NTSTATUS
context_to_server( context_t
*to
, const CONTEXT
*from
)
344 DWORD flags
= from
->ContextFlags
& ~CONTEXT_AMD64
; /* get rid of CPU id */
346 memset( to
, 0, sizeof(*to
) );
347 to
->cpu
= CPU_x86_64
;
349 if (flags
& CONTEXT_CONTROL
)
351 to
->flags
|= SERVER_CTX_CONTROL
;
352 to
->ctl
.x86_64_regs
.rbp
= from
->Rbp
;
353 to
->ctl
.x86_64_regs
.rip
= from
->Rip
;
354 to
->ctl
.x86_64_regs
.rsp
= from
->Rsp
;
355 to
->ctl
.x86_64_regs
.cs
= from
->SegCs
;
356 to
->ctl
.x86_64_regs
.ss
= from
->SegSs
;
357 to
->ctl
.x86_64_regs
.flags
= from
->EFlags
;
358 to
->ctl
.x86_64_regs
.mxcsr
= from
->MxCsr
;
360 if (flags
& CONTEXT_INTEGER
)
362 to
->flags
|= SERVER_CTX_INTEGER
;
363 to
->integer
.x86_64_regs
.rax
= from
->Rax
;
364 to
->integer
.x86_64_regs
.rcx
= from
->Rcx
;
365 to
->integer
.x86_64_regs
.rdx
= from
->Rdx
;
366 to
->integer
.x86_64_regs
.rbx
= from
->Rbx
;
367 to
->integer
.x86_64_regs
.rsi
= from
->Rsi
;
368 to
->integer
.x86_64_regs
.rdi
= from
->Rdi
;
369 to
->integer
.x86_64_regs
.r8
= from
->R8
;
370 to
->integer
.x86_64_regs
.r9
= from
->R9
;
371 to
->integer
.x86_64_regs
.r10
= from
->R10
;
372 to
->integer
.x86_64_regs
.r11
= from
->R11
;
373 to
->integer
.x86_64_regs
.r12
= from
->R12
;
374 to
->integer
.x86_64_regs
.r13
= from
->R13
;
375 to
->integer
.x86_64_regs
.r14
= from
->R14
;
376 to
->integer
.x86_64_regs
.r15
= from
->R15
;
378 if (flags
& CONTEXT_SEGMENTS
)
380 to
->flags
|= SERVER_CTX_SEGMENTS
;
381 to
->seg
.x86_64_regs
.ds
= from
->SegDs
;
382 to
->seg
.x86_64_regs
.es
= from
->SegEs
;
383 to
->seg
.x86_64_regs
.fs
= from
->SegFs
;
384 to
->seg
.x86_64_regs
.gs
= from
->SegGs
;
386 if (flags
& CONTEXT_FLOATING_POINT
)
388 to
->flags
|= SERVER_CTX_FLOATING_POINT
;
389 memcpy( to
->fp
.x86_64_regs
.fpregs
, &from
->u
.FltSave
, sizeof(to
->fp
.x86_64_regs
.fpregs
) );
391 if (flags
& CONTEXT_DEBUG_REGISTERS
)
393 to
->flags
|= SERVER_CTX_DEBUG_REGISTERS
;
394 to
->debug
.x86_64_regs
.dr0
= from
->Dr0
;
395 to
->debug
.x86_64_regs
.dr1
= from
->Dr1
;
396 to
->debug
.x86_64_regs
.dr2
= from
->Dr2
;
397 to
->debug
.x86_64_regs
.dr3
= from
->Dr3
;
398 to
->debug
.x86_64_regs
.dr6
= from
->Dr6
;
399 to
->debug
.x86_64_regs
.dr7
= from
->Dr7
;
401 return STATUS_SUCCESS
;
405 /***********************************************************************
406 * context_from_server
408 * Convert a register context from the server format.
410 NTSTATUS
context_from_server( CONTEXT
*to
, const context_t
*from
)
412 if (from
->cpu
!= CPU_x86_64
) return STATUS_INVALID_PARAMETER
;
414 to
->ContextFlags
= CONTEXT_AMD64
;
415 if (from
->flags
& SERVER_CTX_CONTROL
)
417 to
->ContextFlags
|= CONTEXT_CONTROL
;
418 to
->Rbp
= from
->ctl
.x86_64_regs
.rbp
;
419 to
->Rip
= from
->ctl
.x86_64_regs
.rip
;
420 to
->Rsp
= from
->ctl
.x86_64_regs
.rsp
;
421 to
->SegCs
= from
->ctl
.x86_64_regs
.cs
;
422 to
->SegSs
= from
->ctl
.x86_64_regs
.ss
;
423 to
->EFlags
= from
->ctl
.x86_64_regs
.flags
;
424 to
->MxCsr
= from
->ctl
.x86_64_regs
.mxcsr
;
427 if (from
->flags
& SERVER_CTX_INTEGER
)
429 to
->ContextFlags
|= CONTEXT_INTEGER
;
430 to
->Rax
= from
->integer
.x86_64_regs
.rax
;
431 to
->Rcx
= from
->integer
.x86_64_regs
.rcx
;
432 to
->Rdx
= from
->integer
.x86_64_regs
.rdx
;
433 to
->Rbx
= from
->integer
.x86_64_regs
.rbx
;
434 to
->Rsi
= from
->integer
.x86_64_regs
.rsi
;
435 to
->Rdi
= from
->integer
.x86_64_regs
.rdi
;
436 to
->R8
= from
->integer
.x86_64_regs
.r8
;
437 to
->R9
= from
->integer
.x86_64_regs
.r9
;
438 to
->R10
= from
->integer
.x86_64_regs
.r10
;
439 to
->R11
= from
->integer
.x86_64_regs
.r11
;
440 to
->R12
= from
->integer
.x86_64_regs
.r12
;
441 to
->R13
= from
->integer
.x86_64_regs
.r13
;
442 to
->R14
= from
->integer
.x86_64_regs
.r14
;
443 to
->R15
= from
->integer
.x86_64_regs
.r15
;
445 if (from
->flags
& SERVER_CTX_SEGMENTS
)
447 to
->ContextFlags
|= CONTEXT_SEGMENTS
;
448 to
->SegDs
= from
->seg
.x86_64_regs
.ds
;
449 to
->SegEs
= from
->seg
.x86_64_regs
.es
;
450 to
->SegFs
= from
->seg
.x86_64_regs
.fs
;
451 to
->SegGs
= from
->seg
.x86_64_regs
.gs
;
453 if (from
->flags
& SERVER_CTX_FLOATING_POINT
)
455 to
->ContextFlags
|= CONTEXT_FLOATING_POINT
;
456 memcpy( &to
->u
.FltSave
, from
->fp
.x86_64_regs
.fpregs
, sizeof(from
->fp
.x86_64_regs
.fpregs
) );
458 if (from
->flags
& SERVER_CTX_DEBUG_REGISTERS
)
460 to
->ContextFlags
|= CONTEXT_DEBUG_REGISTERS
;
461 to
->Dr0
= from
->debug
.x86_64_regs
.dr0
;
462 to
->Dr1
= from
->debug
.x86_64_regs
.dr1
;
463 to
->Dr2
= from
->debug
.x86_64_regs
.dr2
;
464 to
->Dr3
= from
->debug
.x86_64_regs
.dr3
;
465 to
->Dr6
= from
->debug
.x86_64_regs
.dr6
;
466 to
->Dr7
= from
->debug
.x86_64_regs
.dr7
;
468 return STATUS_SUCCESS
;
472 /**********************************************************************
475 * Handler for SIGSEGV and related errors.
477 static HANDLER_DEF(segv_handler
)
479 EXCEPTION_RECORD rec
;
482 save_context( &context
, HANDLER_CONTEXT
);
484 rec
.ExceptionRecord
= NULL
;
485 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
486 rec
.ExceptionAddress
= (LPVOID
)context
.Rip
;
487 rec
.NumberParameters
= 0;
489 switch(TRAP_sig(HANDLER_CONTEXT
))
491 case TRAP_x86_OFLOW
: /* Overflow exception */
492 rec
.ExceptionCode
= EXCEPTION_INT_OVERFLOW
;
494 case TRAP_x86_BOUND
: /* Bound range exception */
495 rec
.ExceptionCode
= EXCEPTION_ARRAY_BOUNDS_EXCEEDED
;
497 case TRAP_x86_PRIVINFLT
: /* Invalid opcode exception */
498 rec
.ExceptionCode
= EXCEPTION_ILLEGAL_INSTRUCTION
;
500 case TRAP_x86_STKFLT
: /* Stack fault */
501 rec
.ExceptionCode
= EXCEPTION_STACK_OVERFLOW
;
503 case TRAP_x86_SEGNPFLT
: /* Segment not present exception */
504 case TRAP_x86_PROTFLT
: /* General protection fault */
505 case TRAP_x86_UNKNOWN
: /* Unknown fault code */
506 rec
.ExceptionCode
= ERROR_sig(HANDLER_CONTEXT
) ? EXCEPTION_ACCESS_VIOLATION
507 : EXCEPTION_PRIV_INSTRUCTION
;
509 case TRAP_x86_PAGEFLT
: /* Page fault */
510 rec
.ExceptionCode
= EXCEPTION_ACCESS_VIOLATION
;
512 rec
.NumberParameters
= 2;
513 rec
.ExceptionInformation
[0] = (ERROR_sig(HANDLER_CONTEXT
) & 2) != 0;
514 rec
.ExceptionInformation
[1] = (ULONG_PTR
)FAULT_ADDRESS
;
515 if (!(rec
.ExceptionCode
= virtual_handle_fault( FAULT_ADDRESS
, rec
.ExceptionInformation
[0] )))
519 case TRAP_x86_ALIGNFLT
: /* Alignment check exception */
520 rec
.ExceptionCode
= EXCEPTION_DATATYPE_MISALIGNMENT
;
523 ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT
) );
525 case TRAP_x86_NMI
: /* NMI interrupt */
526 case TRAP_x86_DNA
: /* Device not available exception */
527 case TRAP_x86_DOUBLEFLT
: /* Double fault exception */
528 case TRAP_x86_TSSFLT
: /* Invalid TSS exception */
529 case TRAP_x86_MCHK
: /* Machine check exception */
530 case TRAP_x86_CACHEFLT
: /* Cache flush exception */
531 rec
.ExceptionCode
= EXCEPTION_ILLEGAL_INSTRUCTION
;
535 __regs_RtlRaiseException( &rec
, &context
);
537 restore_context( &context
, HANDLER_CONTEXT
);
540 /**********************************************************************
543 * Handler for SIGTRAP.
545 static HANDLER_DEF(trap_handler
)
547 EXCEPTION_RECORD rec
;
550 save_context( &context
, HANDLER_CONTEXT
);
551 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
552 rec
.ExceptionRecord
= NULL
;
553 rec
.ExceptionAddress
= (LPVOID
)context
.Rip
;
554 rec
.NumberParameters
= 0;
558 case TRAP_TRACE
: /* Single-step exception */
559 rec
.ExceptionCode
= EXCEPTION_SINGLE_STEP
;
560 EFL_sig(HANDLER_CONTEXT
) &= ~0x100; /* clear single-step flag */
562 case TRAP_BRKPT
: /* Breakpoint exception */
563 rec
.ExceptionAddress
= (char *)rec
.ExceptionAddress
- 1; /* back up over the int3 instruction */
566 rec
.ExceptionCode
= EXCEPTION_BREAKPOINT
;
570 __regs_RtlRaiseException( &rec
, &context
);
571 restore_context( &context
, HANDLER_CONTEXT
);
574 /**********************************************************************
577 * Handler for SIGFPE.
579 static HANDLER_DEF(fpe_handler
)
581 EXCEPTION_RECORD rec
;
584 save_context( &context
, HANDLER_CONTEXT
);
585 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
586 rec
.ExceptionRecord
= NULL
;
587 rec
.ExceptionAddress
= (LPVOID
)context
.Rip
;
588 rec
.NumberParameters
= 0;
593 rec
.ExceptionCode
= EXCEPTION_ARRAY_BOUNDS_EXCEEDED
;
596 rec
.ExceptionCode
= EXCEPTION_INT_DIVIDE_BY_ZERO
;
599 rec
.ExceptionCode
= EXCEPTION_INT_OVERFLOW
;
602 rec
.ExceptionCode
= EXCEPTION_FLT_DIVIDE_BY_ZERO
;
605 rec
.ExceptionCode
= EXCEPTION_FLT_OVERFLOW
;
608 rec
.ExceptionCode
= EXCEPTION_FLT_UNDERFLOW
;
611 rec
.ExceptionCode
= EXCEPTION_FLT_INEXACT_RESULT
;
615 rec
.ExceptionCode
= EXCEPTION_FLT_INVALID_OPERATION
;
619 __regs_RtlRaiseException( &rec
, &context
);
620 restore_context( &context
, HANDLER_CONTEXT
);
623 /**********************************************************************
626 * Handler for SIGINT.
628 static HANDLER_DEF(int_handler
)
630 if (!dispatch_signal(SIGINT
))
632 EXCEPTION_RECORD rec
;
635 save_context( &context
, HANDLER_CONTEXT
);
636 rec
.ExceptionCode
= CONTROL_C_EXIT
;
637 rec
.ExceptionFlags
= EXCEPTION_CONTINUABLE
;
638 rec
.ExceptionRecord
= NULL
;
639 rec
.ExceptionAddress
= (LPVOID
)context
.Rip
;
640 rec
.NumberParameters
= 0;
641 __regs_RtlRaiseException( &rec
, &context
);
642 restore_context( &context
, HANDLER_CONTEXT
);
647 /**********************************************************************
650 * Handler for SIGABRT.
652 static HANDLER_DEF(abrt_handler
)
654 EXCEPTION_RECORD rec
;
657 save_context( &context
, HANDLER_CONTEXT
);
658 rec
.ExceptionCode
= EXCEPTION_WINE_ASSERTION
;
659 rec
.ExceptionFlags
= EH_NONCONTINUABLE
;
660 rec
.ExceptionRecord
= NULL
;
661 rec
.ExceptionAddress
= (LPVOID
)context
.Rip
;
662 rec
.NumberParameters
= 0;
663 __regs_RtlRaiseException( &rec
, &context
); /* Should never return.. */
664 restore_context( &context
, HANDLER_CONTEXT
);
668 /**********************************************************************
671 * Handler for SIGQUIT.
673 static HANDLER_DEF(quit_handler
)
679 /**********************************************************************
682 * Handler for SIGUSR1, used to signal a thread that it got suspended.
684 static HANDLER_DEF(usr1_handler
)
688 save_context( &context
, HANDLER_CONTEXT
);
689 wait_suspend( &context
);
690 restore_context( &context
, HANDLER_CONTEXT
);
694 /**********************************************************************
695 * get_signal_stack_total_size
697 * Retrieve the size to allocate for the signal stack, including the TEB at the bottom.
698 * Must be a power of two.
700 size_t get_signal_stack_total_size(void)
702 assert( sizeof(TEB
) <= 2*getpagesize() );
703 return 2*getpagesize(); /* this is just for the TEB, we don't need a signal stack */
707 /***********************************************************************
710 * Set a signal handler
712 static int set_handler( int sig
, void (*func
)() )
714 struct sigaction sig_act
;
716 sig_act
.sa_sigaction
= func
;
717 sig_act
.sa_mask
= server_block_set
;
718 sig_act
.sa_flags
= SA_RESTART
| SA_SIGINFO
| SA_ONSTACK
;
719 return sigaction( sig
, &sig_act
, NULL
);
723 /***********************************************************************
724 * __wine_set_signal_handler (NTDLL.@)
726 int CDECL
__wine_set_signal_handler(unsigned int sig
, wine_signal_handler wsh
)
728 if (sig
> sizeof(handlers
) / sizeof(handlers
[0])) return -1;
729 if (handlers
[sig
] != NULL
) return -2;
735 /**********************************************************************
738 void signal_init_thread( TEB
*teb
)
741 arch_prctl( ARCH_SET_GS
, teb
);
743 # error Please define setting %gs for your architecture
747 /**********************************************************************
748 * signal_init_process
750 void signal_init_process(void)
752 if (set_handler( SIGINT
, (void (*)())int_handler
) == -1) goto error
;
753 if (set_handler( SIGFPE
, (void (*)())fpe_handler
) == -1) goto error
;
754 if (set_handler( SIGSEGV
, (void (*)())segv_handler
) == -1) goto error
;
755 if (set_handler( SIGILL
, (void (*)())segv_handler
) == -1) goto error
;
756 if (set_handler( SIGABRT
, (void (*)())abrt_handler
) == -1) goto error
;
757 if (set_handler( SIGQUIT
, (void (*)())quit_handler
) == -1) goto error
;
758 if (set_handler( SIGUSR1
, (void (*)())usr1_handler
) == -1) goto error
;
760 if (set_handler( SIGBUS
, (void (*)())segv_handler
) == -1) goto error
;
763 if (set_handler( SIGTRAP
, (void (*)())trap_handler
) == -1) goto error
;
773 /**********************************************************************
774 * RtlLookupFunctionEntry (NTDLL.@)
776 PRUNTIME_FUNCTION WINAPI
RtlLookupFunctionEntry( ULONG64 pc
, ULONG64
*base
,
777 UNWIND_HISTORY_TABLE
*table
)
784 /**********************************************************************
785 * RtlVirtualUnwind (NTDLL.@)
787 PVOID WINAPI
RtlVirtualUnwind ( ULONG type
, ULONG64 base
, ULONG64 pc
,
788 RUNTIME_FUNCTION
*function
, CONTEXT
*context
,
789 PVOID
*data
, ULONG64
*frame
,
790 KNONVOLATILE_CONTEXT_POINTERS
*ctx_ptr
)
797 /**********************************************************************
798 * __wine_enter_vm86 (NTDLL.@)
800 void __wine_enter_vm86( CONTEXT
*context
)
802 MESSAGE("vm86 mode not supported on this platform\n");
805 /**********************************************************************
806 * DbgBreakPoint (NTDLL.@)
808 __ASM_GLOBAL_FUNC( DbgBreakPoint
, "int $3; ret")
810 /**********************************************************************
811 * DbgUserBreakPoint (NTDLL.@)
813 __ASM_GLOBAL_FUNC( DbgUserBreakPoint
, "int $3; ret")
815 #endif /* __x86_64__ */