Commit 9968d849 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Use standard siginfo signal handlers on all platforms.

parent 3d7eb3d4
...@@ -69,11 +69,6 @@ static pthread_key_t teb_key; ...@@ -69,11 +69,6 @@ static pthread_key_t teb_key;
*/ */
#ifdef linux #ifdef linux
typedef struct ucontext SIGCONTEXT;
# define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
# define HANDLER_CONTEXT (__context)
/* All Registers access - only for local access */ /* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name) # define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name)
...@@ -104,15 +99,7 @@ typedef struct ucontext SIGCONTEXT; ...@@ -104,15 +99,7 @@ typedef struct ucontext SIGCONTEXT;
#ifdef __APPLE__ #ifdef __APPLE__
# include <sys/ucontext.h> # include <sys/ucontext.h>
# include <sys/types.h> # include <sys/types.h>
typedef siginfo_t siginfo;
typedef struct ucontext SIGCONTEXT;
# define HANDLER_DEF(name) void name( int __signal, siginfo *__siginfo, SIGCONTEXT *__context )
# define HANDLER_CONTEXT (__context)
/* All Registers access - only for local access */ /* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name) # define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name)
...@@ -180,7 +167,7 @@ static inline int dispatch_signal(unsigned int sig) ...@@ -180,7 +167,7 @@ static inline int dispatch_signal(unsigned int sig)
* *
* Set the register values from a sigcontext. * Set the register values from a sigcontext.
*/ */
static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext ) static void save_context( CONTEXT *context, const ucontext_t *sigcontext )
{ {
#define C(x) context->Gpr##x = GPR_sig(x,sigcontext) #define C(x) context->Gpr##x = GPR_sig(x,sigcontext)
...@@ -211,7 +198,7 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext ) ...@@ -211,7 +198,7 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
* *
* Build a sigcontext from the register values. * Build a sigcontext from the register values.
*/ */
static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext ) static void restore_context( const CONTEXT *context, ucontext_t *sigcontext )
{ {
#define C(x) GPR_sig(x,sigcontext) = context->Gpr##x #define C(x) GPR_sig(x,sigcontext) = context->Gpr##x
...@@ -241,7 +228,7 @@ static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext ) ...@@ -241,7 +228,7 @@ static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
* *
* Set the FPU context from a sigcontext. * Set the FPU context from a sigcontext.
*/ */
static inline void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext ) static inline void save_fpu( CONTEXT *context, const ucontext_t *sigcontext )
{ {
#define C(x) context->Fpr##x = FLOAT_sig(x,sigcontext) #define C(x) context->Fpr##x = FLOAT_sig(x,sigcontext)
C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10); C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
...@@ -258,7 +245,7 @@ static inline void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext ) ...@@ -258,7 +245,7 @@ static inline void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
* *
* Restore the FPU context to a sigcontext. * Restore the FPU context to a sigcontext.
*/ */
static inline void restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext ) static inline void restore_fpu( CONTEXT *context, const ucontext_t *sigcontext )
{ {
#define C(x) FLOAT_sig(x,sigcontext) = context->Fpr##x #define C(x) FLOAT_sig(x,sigcontext) = context->Fpr##x
C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10); C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
...@@ -694,59 +681,68 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f ...@@ -694,59 +681,68 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
/********************************************************************** /**********************************************************************
* do_segv * segv_handler
* *
* Implementation of SIGSEGV handler. * Handler for SIGSEGV and related errors.
*/ */
static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr ) static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, sigcontext );
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionAddress = addr; rec.ExceptionAddress = (LPVOID)context.Iar;
rec.NumberParameters = 0; rec.NumberParameters = 0;
switch (trap) { switch (signal)
{
case SIGSEGV: case SIGSEGV:
switch ( code & 0xffff ) { switch (siginfo->si_code & 0xffff)
{
case SEGV_MAPERR: case SEGV_MAPERR:
case SEGV_ACCERR: case SEGV_ACCERR:
rec.NumberParameters = 2; rec.NumberParameters = 2;
rec.ExceptionInformation[0] = 0; /* FIXME ? */ rec.ExceptionInformation[0] = 0; /* FIXME ? */
rec.ExceptionInformation[1] = (ULONG_PTR)addr; rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
if (!(rec.ExceptionCode = virtual_handle_fault(addr, rec.ExceptionInformation[0]))) if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0])))
return; goto done;
break; break;
default:FIXME("Unhandled SIGSEGV/%x\n",code); default:
break; FIXME("Unhandled SIGSEGV/%x\n",siginfo->si_code);
break;
} }
break; break;
case SIGBUS: case SIGBUS:
switch ( code & 0xffff ) { switch (siginfo->si_code & 0xffff)
{
case BUS_ADRALN: case BUS_ADRALN:
rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
break; break;
#ifdef BUS_ADRERR #ifdef BUS_ADRERR
case BUS_ADRERR: case BUS_ADRERR:
#endif #endif
#ifdef BUS_OBJERR #ifdef BUS_OBJERR
case BUS_OBJERR: case BUS_OBJERR:
/* FIXME: correct for all cases ? */ /* FIXME: correct for all cases ? */
rec.NumberParameters = 2; rec.NumberParameters = 2;
rec.ExceptionInformation[0] = 0; /* FIXME ? */ rec.ExceptionInformation[0] = 0; /* FIXME ? */
rec.ExceptionInformation[1] = (ULONG_PTR)addr; rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
if (!(rec.ExceptionCode = virtual_handle_fault(addr, rec.ExceptionInformation[0]))) if (!(rec.ExceptionCode = virtual_handle_fault(siginfo->si_addr, rec.ExceptionInformation[0])))
return; goto done;
break; break;
#endif #endif
default:FIXME("Unhandled SIGBUS/%x\n",code); default:
break; FIXME("Unhandled SIGBUS/%x\n",siginfo->si_code);
break;
} }
break; break;
case SIGILL: case SIGILL:
switch ( code & 0xffff ) { switch (siginfo->si_code & 0xffff)
{
case ILL_ILLOPC: /* illegal opcode */ case ILL_ILLOPC: /* illegal opcode */
#ifdef ILL_ILLOPN #ifdef ILL_ILLOPN
case ILL_ILLOPN: /* illegal operand */ case ILL_ILLOPN: /* illegal operand */
...@@ -760,45 +756,52 @@ static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr ...@@ -760,45 +756,52 @@ static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr
#ifdef ILL_COPROC #ifdef ILL_COPROC
case ILL_COPROC: /* coprocessor error */ case ILL_COPROC: /* coprocessor error */
#endif #endif
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
case ILL_PRVOPC: /* privileged opcode */ case ILL_PRVOPC: /* privileged opcode */
#ifdef ILL_PRVREG #ifdef ILL_PRVREG
case ILL_PRVREG: /* privileged register */ case ILL_PRVREG: /* privileged register */
#endif #endif
rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION; rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
break; break;
#ifdef ILL_BADSTK #ifdef ILL_BADSTK
case ILL_BADSTK: /* internal stack error */ case ILL_BADSTK: /* internal stack error */
rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW; rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
break; break;
#endif #endif
default:FIXME("Unhandled SIGILL/%x\n", code); default:
break; FIXME("Unhandled SIGILL/%x\n", siginfo->si_code);
break;
} }
break; break;
} }
status = raise_exception( &rec, context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
done:
restore_context( &context, sigcontext );
} }
/********************************************************************** /**********************************************************************
* do_trap * trap_handler
* *
* Implementation of SIGTRAP handler. * Handler for SIGTRAP.
*/ */
static void do_trap( CONTEXT *context, int code, void * addr ) static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, sigcontext );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionAddress = addr; rec.ExceptionAddress = (LPVOID)context.Iar;
rec.NumberParameters = 0; rec.NumberParameters = 0;
/* FIXME: check if we might need to modify PC */ /* FIXME: check if we might need to modify PC */
switch (code & 0xffff) { switch (siginfo->si_code & 0xffff)
{
#ifdef TRAP_BRKPT #ifdef TRAP_BRKPT
case TRAP_BRKPT: case TRAP_BRKPT:
rec.ExceptionCode = EXCEPTION_BREAKPOINT; rec.ExceptionCode = EXCEPTION_BREAKPOINT;
...@@ -809,24 +812,31 @@ static void do_trap( CONTEXT *context, int code, void * addr ) ...@@ -809,24 +812,31 @@ static void do_trap( CONTEXT *context, int code, void * addr )
rec.ExceptionCode = EXCEPTION_SINGLE_STEP; rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
break; break;
#endif #endif
default:FIXME("Unhandled SIGTRAP/%x\n", code); default:
break; FIXME("Unhandled SIGTRAP/%x\n", siginfo->si_code);
break;
} }
status = raise_exception( &rec, context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, sigcontext );
} }
/********************************************************************** /**********************************************************************
* do_trap * fpe_handler
* *
* Implementation of SIGFPE handler. * Handler for SIGFPE.
*/ */
static void do_fpe( CONTEXT *context, int code, void * addr ) static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status; NTSTATUS status;
switch ( code & 0xffff ) { save_fpu( &context, sigcontext );
save_context( &context, sigcontext );
switch (siginfo->si_code & 0xffff )
{
#ifdef FPE_FLTSUB #ifdef FPE_FLTSUB
case FPE_FLTSUB: case FPE_FLTSUB:
rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
...@@ -871,51 +881,13 @@ static void do_fpe( CONTEXT *context, int code, void * addr ) ...@@ -871,51 +881,13 @@ static void do_fpe( CONTEXT *context, int code, void * addr )
} }
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionAddress = addr; rec.ExceptionAddress = (LPVOID)context.Iar;
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
}
/**********************************************************************
* segv_handler
*
* Handler for SIGSEGV and related errors.
*/
static HANDLER_DEF(segv_handler)
{
CONTEXT context;
save_context( &context, HANDLER_CONTEXT );
do_segv( &context, __siginfo->si_signo, __siginfo->si_errno, __siginfo->si_code, __siginfo->si_addr );
restore_context( &context, HANDLER_CONTEXT );
}
/********************************************************************** restore_context( &context, sigcontext );
* trap_handler restore_fpu( &context, sigcontext );
*
* Handler for SIGTRAP.
*/
static HANDLER_DEF(trap_handler)
{
CONTEXT context;
save_context( &context, HANDLER_CONTEXT );
do_trap( &context, __siginfo->si_code, __siginfo->si_addr );
restore_context( &context, HANDLER_CONTEXT );
}
/**********************************************************************
* fpe_handler
*
* Handler for SIGFPE.
*/
static HANDLER_DEF(fpe_handler)
{
CONTEXT context;
save_fpu( &context, HANDLER_CONTEXT );
save_context( &context, HANDLER_CONTEXT );
do_fpe( &context, __siginfo->si_code, __siginfo->si_addr );
restore_context( &context, HANDLER_CONTEXT );
restore_fpu( &context, HANDLER_CONTEXT );
} }
/********************************************************************** /**********************************************************************
...@@ -923,7 +895,7 @@ static HANDLER_DEF(fpe_handler) ...@@ -923,7 +895,7 @@ static HANDLER_DEF(fpe_handler)
* *
* Handler for SIGINT. * Handler for SIGINT.
*/ */
static HANDLER_DEF(int_handler) static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
if (!dispatch_signal(SIGINT)) if (!dispatch_signal(SIGINT))
{ {
...@@ -931,7 +903,7 @@ static HANDLER_DEF(int_handler) ...@@ -931,7 +903,7 @@ static HANDLER_DEF(int_handler)
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, sigcontext );
rec.ExceptionCode = CONTROL_C_EXIT; rec.ExceptionCode = CONTROL_C_EXIT;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
...@@ -939,7 +911,7 @@ static HANDLER_DEF(int_handler) ...@@ -939,7 +911,7 @@ static HANDLER_DEF(int_handler)
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, sigcontext );
} }
} }
...@@ -949,13 +921,13 @@ static HANDLER_DEF(int_handler) ...@@ -949,13 +921,13 @@ static HANDLER_DEF(int_handler)
* *
* Handler for SIGABRT. * Handler for SIGABRT.
*/ */
static HANDLER_DEF(abrt_handler) static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, sigcontext );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION; rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
rec.ExceptionFlags = EH_NONCONTINUABLE; rec.ExceptionFlags = EH_NONCONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
...@@ -963,7 +935,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -963,7 +935,7 @@ static HANDLER_DEF(abrt_handler)
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, sigcontext );
} }
...@@ -972,7 +944,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -972,7 +944,7 @@ static HANDLER_DEF(abrt_handler)
* *
* Handler for SIGQUIT. * Handler for SIGQUIT.
*/ */
static HANDLER_DEF(quit_handler) static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
abort_thread(0); abort_thread(0);
} }
...@@ -983,13 +955,13 @@ static HANDLER_DEF(quit_handler) ...@@ -983,13 +955,13 @@ static HANDLER_DEF(quit_handler)
* *
* Handler for SIGUSR1, used to signal a thread that it got suspended. * Handler for SIGUSR1, used to signal a thread that it got suspended.
*/ */
static HANDLER_DEF(usr1_handler) static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
CONTEXT context; CONTEXT context;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, sigcontext );
wait_suspend( &context ); wait_suspend( &context );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, sigcontext );
} }
...@@ -1007,22 +979,6 @@ size_t get_signal_stack_total_size(void) ...@@ -1007,22 +979,6 @@ size_t get_signal_stack_total_size(void)
/*********************************************************************** /***********************************************************************
* set_handler
*
* Set a signal handler
*/
static int set_handler( int sig, void (*func)() )
{
struct sigaction sig_act;
sig_act.sa_sigaction = func;
sig_act.sa_mask = server_block_set;
sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
return sigaction( sig, &sig_act, NULL );
}
/***********************************************************************
* __wine_set_signal_handler (NTDLL.@) * __wine_set_signal_handler (NTDLL.@)
*/ */
int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh) int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
...@@ -1055,18 +1011,32 @@ void signal_init_thread( TEB *teb ) ...@@ -1055,18 +1011,32 @@ void signal_init_thread( TEB *teb )
*/ */
void signal_init_process(void) void signal_init_process(void)
{ {
if (set_handler( SIGINT, (void (*)())int_handler ) == -1) goto error; struct sigaction sig_act;
if (set_handler( SIGFPE, (void (*)())fpe_handler ) == -1) goto error;
if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error; sig_act.sa_mask = server_block_set;
if (set_handler( SIGILL, (void (*)())segv_handler ) == -1) goto error; sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error;
if (set_handler( SIGQUIT, (void (*)())quit_handler ) == -1) goto error; sig_act.sa_sigaction = int_handler;
if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error; if (sigaction( SIGINT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = fpe_handler;
if (sigaction( SIGFPE, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = abrt_handler;
if (sigaction( SIGABRT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = quit_handler;
if (sigaction( SIGQUIT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = usr1_handler;
if (sigaction( SIGUSR1, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = segv_handler;
if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
#ifdef SIGBUS #ifdef SIGBUS
if (set_handler( SIGBUS, (void (*)())segv_handler ) == -1) goto error; if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
#endif #endif
#ifdef SIGTRAP #ifdef SIGTRAP
if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error; sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif #endif
return; return;
......
...@@ -48,9 +48,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh); ...@@ -48,9 +48,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
static pthread_key_t teb_key; static pthread_key_t teb_key;
#define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, ucontext_t *__context )
#define HANDLER_CONTEXT (__context)
typedef int (*wine_signal_handler)(unsigned int sig); typedef int (*wine_signal_handler)(unsigned int sig);
static wine_signal_handler handlers[256]; static wine_signal_handler handlers[256];
...@@ -449,7 +446,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) ...@@ -449,7 +446,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
* *
* Handler for SIGSEGV. * Handler for SIGSEGV.
*/ */
static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void segv_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
...@@ -479,7 +476,7 @@ static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -479,7 +476,7 @@ static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGBUS. * Handler for SIGBUS.
*/ */
static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void bus_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
...@@ -506,7 +503,7 @@ static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -506,7 +503,7 @@ static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGILL. * Handler for SIGILL.
*/ */
static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void ill_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
...@@ -548,7 +545,7 @@ static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -548,7 +545,7 @@ static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGTRAP. * Handler for SIGTRAP.
*/ */
static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void trap_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
...@@ -581,7 +578,7 @@ static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -581,7 +578,7 @@ static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGFPE. * Handler for SIGFPE.
*/ */
static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void fpe_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
...@@ -634,7 +631,7 @@ static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -634,7 +631,7 @@ static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGINT. * Handler for SIGINT.
*/ */
static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) static void int_handler( int signal, siginfo_t *info, void *ucontext )
{ {
if (!dispatch_signal(SIGINT)) if (!dispatch_signal(SIGINT))
{ {
...@@ -659,13 +656,13 @@ static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext ) ...@@ -659,13 +656,13 @@ static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
* *
* Handler for SIGABRT. * Handler for SIGABRT.
*/ */
static HANDLER_DEF(abrt_handler) static void abrt_handler( int signal, struct siginfo *info, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION; rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
rec.ExceptionFlags = EH_NONCONTINUABLE; rec.ExceptionFlags = EH_NONCONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
...@@ -673,7 +670,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -673,7 +670,7 @@ static HANDLER_DEF(abrt_handler)
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
...@@ -682,7 +679,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -682,7 +679,7 @@ static HANDLER_DEF(abrt_handler)
* *
* Handler for SIGQUIT. * Handler for SIGQUIT.
*/ */
static HANDLER_DEF(quit_handler) static void quit_handler( int signal, struct siginfo *info, void *ucontext )
{ {
abort_thread(0); abort_thread(0);
} }
...@@ -693,13 +690,13 @@ static HANDLER_DEF(quit_handler) ...@@ -693,13 +690,13 @@ static HANDLER_DEF(quit_handler)
* *
* Handler for SIGUSR1, used to signal a thread that it got suspended. * Handler for SIGUSR1, used to signal a thread that it got suspended.
*/ */
static HANDLER_DEF(usr1_handler) static void usr1_handler( int signal, struct siginfo *info, void *ucontext )
{ {
CONTEXT context; CONTEXT context;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
wait_suspend( &context ); wait_suspend( &context );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
...@@ -717,23 +714,6 @@ size_t get_signal_stack_total_size(void) ...@@ -717,23 +714,6 @@ size_t get_signal_stack_total_size(void)
/*********************************************************************** /***********************************************************************
* set_handler
*
* Set a signal handler
*/
static int set_handler( int sig, void (*func)() )
{
struct sigaction sig_act;
sig_act.sa_sigaction = func;
sig_act.sa_mask = server_block_set;
sig_act.sa_flags = SA_SIGINFO;
return sigaction( sig, &sig_act, NULL );
}
/***********************************************************************
* __wine_set_signal_handler (NTDLL.@) * __wine_set_signal_handler (NTDLL.@)
*/ */
int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh) int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
...@@ -766,15 +746,34 @@ void signal_init_thread( TEB *teb ) ...@@ -766,15 +746,34 @@ void signal_init_thread( TEB *teb )
*/ */
void signal_init_process(void) void signal_init_process(void)
{ {
if (set_handler( SIGINT, (void (*)())int_handler ) == -1) goto error; struct sigaction sig_act;
if (set_handler( SIGFPE, (void (*)())fpe_handler ) == -1) goto error;
if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error; sig_act.sa_mask = server_block_set;
if (set_handler( SIGILL, (void (*)())ill_handler ) == -1) goto error; sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
if (set_handler( SIGBUS, (void (*)())bus_handler ) == -1) goto error;
if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error; sig_act.sa_sigaction = int_handler;
if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error; if (sigaction( SIGINT, &sig_act, NULL ) == -1) goto error;
if (set_handler( SIGQUIT, (void (*)())quit_handler ) == -1) goto error; sig_act.sa_sigaction = fpe_handler;
if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error; if (sigaction( SIGFPE, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = abrt_handler;
if (sigaction( SIGABRT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = quit_handler;
if (sigaction( SIGQUIT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = usr1_handler;
if (sigaction( SIGUSR1, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = segv_handler;
if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
#ifdef SIGBUS
if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
#endif
#ifdef SIGTRAP
sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif
/* 'ta 6' tells the kernel to synthesize any unaligned accesses this /* 'ta 6' tells the kernel to synthesize any unaligned accesses this
process makes, instead of just signalling an error and terminating process makes, instead of just signalling an error and terminating
the process. wine-devel did not reach a conclusion on whether the process. wine-devel did not reach a conclusion on whether
......
...@@ -60,11 +60,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh); ...@@ -60,11 +60,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
#include <asm/prctl.h> #include <asm/prctl.h>
extern int arch_prctl(int func, void *ptr); extern int arch_prctl(int func, void *ptr);
typedef struct ucontext SIGCONTEXT;
# define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
# define HANDLER_CONTEXT (__context)
#define RAX_sig(context) ((context)->uc_mcontext.gregs[REG_RAX]) #define RAX_sig(context) ((context)->uc_mcontext.gregs[REG_RAX])
#define RBX_sig(context) ((context)->uc_mcontext.gregs[REG_RBX]) #define RBX_sig(context) ((context)->uc_mcontext.gregs[REG_RBX])
#define RCX_sig(context) ((context)->uc_mcontext.gregs[REG_RCX]) #define RCX_sig(context) ((context)->uc_mcontext.gregs[REG_RCX])
...@@ -93,9 +88,6 @@ typedef struct ucontext SIGCONTEXT; ...@@ -93,9 +88,6 @@ typedef struct ucontext SIGCONTEXT;
#define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.fpregs)) #define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.fpregs))
#define FAULT_CODE (__siginfo->si_code)
#define FAULT_ADDRESS (__siginfo->si_addr)
#endif /* linux */ #endif /* linux */
#if defined(__NetBSD__) #if defined(__NetBSD__)
...@@ -103,8 +95,6 @@ typedef struct ucontext SIGCONTEXT; ...@@ -103,8 +95,6 @@ typedef struct ucontext SIGCONTEXT;
# include <sys/types.h> # include <sys/types.h>
# include <signal.h> # include <signal.h>
typedef ucontext_t SIGCONTEXT;
#define RAX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RAX]) #define RAX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RAX])
#define RBX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RBX]) #define RBX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RBX])
#define RCX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RCX]) #define RCX_sig(context) ((context)->uc_mcontext.__gregs[_REG_RCX])
...@@ -136,12 +126,6 @@ typedef ucontext_t SIGCONTEXT; ...@@ -136,12 +126,6 @@ typedef ucontext_t SIGCONTEXT;
#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
#define FAULT_CODE (__siginfo->si_code)
#define FAULT_ADDRESS (__siginfo->si_addr)
#define HANDLER_DEF(name) void name( int __signal, siginfo_t *__siginfo, SIGCONTEXT *__context )
#define HANDLER_CONTEXT (__context)
#define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs)) #define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs))
#endif /* __NetBSD__ */ #endif /* __NetBSD__ */
...@@ -187,7 +171,7 @@ static inline int dispatch_signal(unsigned int sig) ...@@ -187,7 +171,7 @@ static inline int dispatch_signal(unsigned int sig)
* *
* Set the register values from a sigcontext. * Set the register values from a sigcontext.
*/ */
static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext ) static void save_context( CONTEXT *context, const ucontext_t *sigcontext )
{ {
context->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; context->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS;
context->Rax = RAX_sig(sigcontext); context->Rax = RAX_sig(sigcontext);
...@@ -228,7 +212,7 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext ) ...@@ -228,7 +212,7 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
* *
* Build a sigcontext from the register values. * Build a sigcontext from the register values.
*/ */
static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext ) static void restore_context( const CONTEXT *context, ucontext_t *sigcontext )
{ {
RAX_sig(sigcontext) = context->Rax; RAX_sig(sigcontext) = context->Rax;
RCX_sig(sigcontext) = context->Rcx; RCX_sig(sigcontext) = context->Rcx;
...@@ -562,20 +546,21 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f ...@@ -562,20 +546,21 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
* *
* Handler for SIGSEGV and related errors. * Handler for SIGSEGV and related errors.
*/ */
static HANDLER_DEF(segv_handler) static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
ucontext_t *ucontext = sigcontext;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionAddress = (LPVOID)context.Rip; rec.ExceptionAddress = (LPVOID)context.Rip;
rec.NumberParameters = 0; rec.NumberParameters = 0;
switch(TRAP_sig(HANDLER_CONTEXT)) switch(TRAP_sig(ucontext))
{ {
case TRAP_x86_OFLOW: /* Overflow exception */ case TRAP_x86_OFLOW: /* Overflow exception */
rec.ExceptionCode = EXCEPTION_INT_OVERFLOW; rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
...@@ -592,24 +577,22 @@ static HANDLER_DEF(segv_handler) ...@@ -592,24 +577,22 @@ static HANDLER_DEF(segv_handler)
case TRAP_x86_SEGNPFLT: /* Segment not present exception */ case TRAP_x86_SEGNPFLT: /* Segment not present exception */
case TRAP_x86_PROTFLT: /* General protection fault */ case TRAP_x86_PROTFLT: /* General protection fault */
case TRAP_x86_UNKNOWN: /* Unknown fault code */ case TRAP_x86_UNKNOWN: /* Unknown fault code */
rec.ExceptionCode = ERROR_sig(HANDLER_CONTEXT) ? EXCEPTION_ACCESS_VIOLATION rec.ExceptionCode = ERROR_sig(ucontext) ? EXCEPTION_ACCESS_VIOLATION
: EXCEPTION_PRIV_INSTRUCTION; : EXCEPTION_PRIV_INSTRUCTION;
break; break;
case TRAP_x86_PAGEFLT: /* Page fault */ case TRAP_x86_PAGEFLT: /* Page fault */
rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION; rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
#ifdef FAULT_ADDRESS
rec.NumberParameters = 2; rec.NumberParameters = 2;
rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0; rec.ExceptionInformation[0] = (ERROR_sig(ucontext) & 2) != 0;
rec.ExceptionInformation[1] = (ULONG_PTR)FAULT_ADDRESS; rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
if (!(rec.ExceptionCode = virtual_handle_fault( FAULT_ADDRESS, rec.ExceptionInformation[0] ))) if (!(rec.ExceptionCode = virtual_handle_fault( siginfo->si_addr, rec.ExceptionInformation[0] )))
goto done; goto done;
#endif
break; break;
case TRAP_x86_ALIGNFLT: /* Alignment check exception */ case TRAP_x86_ALIGNFLT: /* Alignment check exception */
rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
break; break;
default: default:
ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) ); ERR( "Got unexpected trap %ld\n", TRAP_sig(ucontext) );
/* fall through */ /* fall through */
case TRAP_x86_NMI: /* NMI interrupt */ case TRAP_x86_NMI: /* NMI interrupt */
case TRAP_x86_DNA: /* Device not available exception */ case TRAP_x86_DNA: /* Device not available exception */
...@@ -624,7 +607,7 @@ static HANDLER_DEF(segv_handler) ...@@ -624,7 +607,7 @@ static HANDLER_DEF(segv_handler)
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
done: done:
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
/********************************************************************** /**********************************************************************
...@@ -632,23 +615,24 @@ done: ...@@ -632,23 +615,24 @@ done:
* *
* Handler for SIGTRAP. * Handler for SIGTRAP.
*/ */
static HANDLER_DEF(trap_handler) static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
ucontext_t *ucontext = sigcontext;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Rip; rec.ExceptionAddress = (LPVOID)context.Rip;
rec.NumberParameters = 0; rec.NumberParameters = 0;
switch(FAULT_CODE) switch (siginfo->si_code)
{ {
case TRAP_TRACE: /* Single-step exception */ case TRAP_TRACE: /* Single-step exception */
rec.ExceptionCode = EXCEPTION_SINGLE_STEP; rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
EFL_sig(HANDLER_CONTEXT) &= ~0x100; /* clear single-step flag */ EFL_sig(ucontext) &= ~0x100; /* clear single-step flag */
break; break;
case TRAP_BRKPT: /* Breakpoint exception */ case TRAP_BRKPT: /* Breakpoint exception */
rec.ExceptionAddress = (char *)rec.ExceptionAddress - 1; /* back up over the int3 instruction */ rec.ExceptionAddress = (char *)rec.ExceptionAddress - 1; /* back up over the int3 instruction */
...@@ -660,7 +644,7 @@ static HANDLER_DEF(trap_handler) ...@@ -660,7 +644,7 @@ static HANDLER_DEF(trap_handler)
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
/********************************************************************** /**********************************************************************
...@@ -668,19 +652,19 @@ static HANDLER_DEF(trap_handler) ...@@ -668,19 +652,19 @@ static HANDLER_DEF(trap_handler)
* *
* Handler for SIGFPE. * Handler for SIGFPE.
*/ */
static HANDLER_DEF(fpe_handler) static void fpe_handler( int signal, siginfo_t *siginfo, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Rip; rec.ExceptionAddress = (LPVOID)context.Rip;
rec.NumberParameters = 0; rec.NumberParameters = 0;
switch (FAULT_CODE) switch (siginfo->si_code)
{ {
case FPE_FLTSUB: case FPE_FLTSUB:
rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
...@@ -711,7 +695,7 @@ static HANDLER_DEF(fpe_handler) ...@@ -711,7 +695,7 @@ static HANDLER_DEF(fpe_handler)
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
/********************************************************************** /**********************************************************************
...@@ -719,7 +703,7 @@ static HANDLER_DEF(fpe_handler) ...@@ -719,7 +703,7 @@ static HANDLER_DEF(fpe_handler)
* *
* Handler for SIGINT. * Handler for SIGINT.
*/ */
static HANDLER_DEF(int_handler) static void int_handler( int signal, siginfo_t *siginfo, void *ucontext )
{ {
if (!dispatch_signal(SIGINT)) if (!dispatch_signal(SIGINT))
{ {
...@@ -727,7 +711,7 @@ static HANDLER_DEF(int_handler) ...@@ -727,7 +711,7 @@ static HANDLER_DEF(int_handler)
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionCode = CONTROL_C_EXIT; rec.ExceptionCode = CONTROL_C_EXIT;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
...@@ -735,7 +719,7 @@ static HANDLER_DEF(int_handler) ...@@ -735,7 +719,7 @@ static HANDLER_DEF(int_handler)
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
} }
...@@ -745,13 +729,13 @@ static HANDLER_DEF(int_handler) ...@@ -745,13 +729,13 @@ static HANDLER_DEF(int_handler)
* *
* Handler for SIGABRT. * Handler for SIGABRT.
*/ */
static HANDLER_DEF(abrt_handler) static void abrt_handler( int signal, siginfo_t *siginfo, void *ucontext )
{ {
EXCEPTION_RECORD rec; EXCEPTION_RECORD rec;
CONTEXT context; CONTEXT context;
NTSTATUS status; NTSTATUS status;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION; rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
rec.ExceptionFlags = EH_NONCONTINUABLE; rec.ExceptionFlags = EH_NONCONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
...@@ -759,7 +743,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -759,7 +743,7 @@ static HANDLER_DEF(abrt_handler)
rec.NumberParameters = 0; rec.NumberParameters = 0;
status = raise_exception( &rec, &context, TRUE ); status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec ); if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
...@@ -768,7 +752,7 @@ static HANDLER_DEF(abrt_handler) ...@@ -768,7 +752,7 @@ static HANDLER_DEF(abrt_handler)
* *
* Handler for SIGQUIT. * Handler for SIGQUIT.
*/ */
static HANDLER_DEF(quit_handler) static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext )
{ {
abort_thread(0); abort_thread(0);
} }
...@@ -779,13 +763,13 @@ static HANDLER_DEF(quit_handler) ...@@ -779,13 +763,13 @@ static HANDLER_DEF(quit_handler)
* *
* Handler for SIGUSR1, used to signal a thread that it got suspended. * Handler for SIGUSR1, used to signal a thread that it got suspended.
*/ */
static HANDLER_DEF(usr1_handler) static void usr1_handler( int signal, siginfo_t *siginfo, void *ucontext )
{ {
CONTEXT context; CONTEXT context;
save_context( &context, HANDLER_CONTEXT ); save_context( &context, ucontext );
wait_suspend( &context ); wait_suspend( &context );
restore_context( &context, HANDLER_CONTEXT ); restore_context( &context, ucontext );
} }
...@@ -803,22 +787,6 @@ size_t get_signal_stack_total_size(void) ...@@ -803,22 +787,6 @@ size_t get_signal_stack_total_size(void)
/*********************************************************************** /***********************************************************************
* set_handler
*
* Set a signal handler
*/
static int set_handler( int sig, void (*func)() )
{
struct sigaction sig_act;
sig_act.sa_sigaction = func;
sig_act.sa_mask = server_block_set;
sig_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
return sigaction( sig, &sig_act, NULL );
}
/***********************************************************************
* __wine_set_signal_handler (NTDLL.@) * __wine_set_signal_handler (NTDLL.@)
*/ */
int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh) int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
...@@ -847,18 +815,32 @@ void signal_init_thread( TEB *teb ) ...@@ -847,18 +815,32 @@ void signal_init_thread( TEB *teb )
*/ */
void signal_init_process(void) void signal_init_process(void)
{ {
if (set_handler( SIGINT, (void (*)())int_handler ) == -1) goto error; struct sigaction sig_act;
if (set_handler( SIGFPE, (void (*)())fpe_handler ) == -1) goto error;
if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error; sig_act.sa_mask = server_block_set;
if (set_handler( SIGILL, (void (*)())segv_handler ) == -1) goto error; sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
if (set_handler( SIGABRT, (void (*)())abrt_handler ) == -1) goto error;
if (set_handler( SIGQUIT, (void (*)())quit_handler ) == -1) goto error; sig_act.sa_sigaction = int_handler;
if (set_handler( SIGUSR1, (void (*)())usr1_handler ) == -1) goto error; if (sigaction( SIGINT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = fpe_handler;
if (sigaction( SIGFPE, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = abrt_handler;
if (sigaction( SIGABRT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = quit_handler;
if (sigaction( SIGQUIT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = usr1_handler;
if (sigaction( SIGUSR1, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = segv_handler;
if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
#ifdef SIGBUS #ifdef SIGBUS
if (set_handler( SIGBUS, (void (*)())segv_handler ) == -1) goto error; if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
#endif #endif
#ifdef SIGTRAP #ifdef SIGTRAP
if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error; sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif #endif
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment