Moved all signal support to a new platform-specific file.
Make use of the per-thread signal stack (Juergen Lock).
Fixed %fs in signal handler for non FS_sig case (Ulrich Weigand).
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 6374ca7..8a88bdc 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -16,6 +16,7 @@
rtl.c \
rtlstr.c \
sec.c \
+ signal_i386.c \
sync.c \
time.c
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index ef578fb..15adadb 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -12,7 +12,6 @@
#include "global.h"
#include "wine/exception.h"
#include "stackframe.h"
-#include "sig_context.h"
#include "miscemu.h"
#include "debugtools.h"
@@ -25,10 +24,11 @@
EXCEPTION_FRAME *prevFrame;
} EXC_NESTED_FRAME;
+
#ifdef __i386__
-# define GET_IP(context) ((LPVOID)EIP_reg(context))
+# define GET_IP(context) ((LPVOID)(context)->Eip)
#else
-# define GET_IP(context) ((LPVOID)0)
+# error You must define GET_IP for this CPU
#endif /* __i386__ */
/* Default hook for built-in debugger */
@@ -224,7 +224,7 @@
PEXCEPTION_FRAME frame, dispatch;
#ifdef __i386__
- EAX_reg(context) = returnEax;
+ context->Eax = returnEax;
#endif
/* build an exception record, if we do not have one */
@@ -343,362 +343,3 @@
REGS_FUNC(DebugBreak)( context );
#endif /* defined(__i386__) */
}
-
-
-/***********************************************************************
- * EXC_SaveContext
- *
- * Set the register values from a sigcontext.
- */
-static void EXC_SaveContext( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
- EAX_reg(context) = EAX_sig(sigcontext);
- EBX_reg(context) = EBX_sig(sigcontext);
- ECX_reg(context) = ECX_sig(sigcontext);
- EDX_reg(context) = EDX_sig(sigcontext);
- ESI_reg(context) = ESI_sig(sigcontext);
- EDI_reg(context) = EDI_sig(sigcontext);
- EBP_reg(context) = EBP_sig(sigcontext);
- EFL_reg(context) = EFL_sig(sigcontext);
- EIP_reg(context) = EIP_sig(sigcontext);
- ESP_reg(context) = ESP_sig(sigcontext);
- CS_reg(context) = LOWORD(CS_sig(sigcontext));
- DS_reg(context) = LOWORD(DS_sig(sigcontext));
- ES_reg(context) = LOWORD(ES_sig(sigcontext));
- SS_reg(context) = LOWORD(SS_sig(sigcontext));
-#ifdef FS_sig
- FS_reg(context) = LOWORD(FS_sig(sigcontext));
-#else
- GET_FS( FS_reg(context) );
- FS_reg(context) &= 0xffff;
-#endif
-#ifdef GS_sig
- GS_reg(context) = LOWORD(GS_sig(sigcontext));
-#else
- GET_GS( GS_reg(context) );
- GS_reg(context) &= 0xffff;
-#endif
- if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
-#endif /* __i386__ */
-}
-
-
-/***********************************************************************
- * EXC_RestoreContext
- *
- * Build a sigcontext from the register values.
- */
-static void EXC_RestoreContext( const CONTEXT *context, SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
- EAX_sig(sigcontext) = EAX_reg(context);
- EBX_sig(sigcontext) = EBX_reg(context);
- ECX_sig(sigcontext) = ECX_reg(context);
- EDX_sig(sigcontext) = EDX_reg(context);
- ESI_sig(sigcontext) = ESI_reg(context);
- EDI_sig(sigcontext) = EDI_reg(context);
- EBP_sig(sigcontext) = EBP_reg(context);
- EFL_sig(sigcontext) = EFL_reg(context);
- EIP_sig(sigcontext) = EIP_reg(context);
- ESP_sig(sigcontext) = ESP_reg(context);
- CS_sig(sigcontext) = CS_reg(context);
- DS_sig(sigcontext) = DS_reg(context);
- ES_sig(sigcontext) = ES_reg(context);
- SS_sig(sigcontext) = SS_reg(context);
-#ifdef FS_sig
- FS_sig(sigcontext) = FS_reg(context);
-#else
- SET_FS( FS_reg(context) );
-#endif
-#ifdef GS_sig
- GS_sig(sigcontext) = GS_reg(context);
-#else
- SET_GS( GS_reg(context) );
-#endif
-#endif /* __i386__ */
-}
-
-
-/**********************************************************************
- * EXC_segv
- *
- * Handler for SIGSEGV and related errors.
- */
-static HANDLER_DEF(EXC_segv)
-{
- EXCEPTION_RECORD rec;
- CONTEXT context;
-
- HANDLER_INIT();
-
-#if defined(TRAP_sig) && defined(CR2_sig)
- /* we want the page-fault case to be fast */
- if (TRAP_sig(HANDLER_CONTEXT) == 14)
- if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return;
-#endif
-
- EXC_SaveContext( &context, HANDLER_CONTEXT );
- rec.ExceptionRecord = NULL;
- rec.ExceptionFlags = 0;
- rec.ExceptionAddress = GET_IP(&context);
- rec.NumberParameters = 0;
-
-#ifdef TRAP_sig
- switch(TRAP_sig(HANDLER_CONTEXT))
- {
- case 4: /* Overflow exception */
- rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
- break;
- case 5: /* Bound range exception */
- rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
- break;
- case 6: /* Invalid opcode exception */
- rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
- break;
- case 12: /* Stack fault */
- rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
- break;
- case 11: /* Segment not present exception */
- case 13: /* General protection fault */
- if (INSTR_EmulateInstruction( &context )) goto restore;
- rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
- break;
- case 14: /* Page fault */
-#ifdef CR2_sig
- rec.NumberParameters = 2;
-#ifdef ERROR_sig
- rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0;
-#else
- rec.ExceptionInformation[0] = 0;
-#endif /* ERROR_sig */
- rec.ExceptionInformation[1] = CR2_sig(HANDLER_CONTEXT);
-#endif /* CR2_sig */
- rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
- break;
- case 17: /* Alignment check exception */
- /* FIXME: pass through exception handler first? */
- if (EFL_reg(&context) & 0x00040000)
- {
- /* Disable AC flag, return */
- EFL_reg(&context) &= ~0x00040000;
- goto restore;
- }
- rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
- break;
- default:
- ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
- /* fall through */
- case 2: /* NMI interrupt */
- case 7: /* Device not available exception */
- case 8: /* Double fault exception */
- case 10: /* Invalid TSS exception */
- case 15: /* Unknown exception */
- case 18: /* Machine check exception */
- case 19: /* Cache flush exception */
- rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
- break;
- }
-#else /* TRAP_sig */
-# ifdef __i386__
- if (INSTR_EmulateInstruction( &context )) goto restore;
-# endif
- rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; /* generic error */
-#endif /* TRAP_sig */
-
- REGS_FUNC(RtlRaiseException)( &rec, &context );
- restore:
- EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- * EXC_trap
- *
- * Handler for SIGTRAP.
- */
-static HANDLER_DEF(EXC_trap)
-{
- EXCEPTION_RECORD rec;
- CONTEXT context;
-
- HANDLER_INIT();
-
-#ifdef TRAP_sig
- rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ?
- EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT;
-#else
- rec.ExceptionCode = EXCEPTION_BREAKPOINT;
-#endif /* TRAP_sig */
-
- EXC_SaveContext( &context, HANDLER_CONTEXT );
- rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
- rec.ExceptionRecord = NULL;
- rec.ExceptionAddress = GET_IP(&context);
- rec.NumberParameters = 0;
- REGS_FUNC(RtlRaiseException)( &rec, &context );
- EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/***********************************************************************
- * EXC_SaveFPU
- *
- * Set the FPU context from a sigcontext.
- */
-static void inline EXC_SaveFPU( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-# ifdef FPU_sig
- if (FPU_sig(sigcontext))
- {
- context->FloatSave = *FPU_sig(sigcontext);
- return;
- }
-# endif /* FPU_sig */
-# ifdef __GNUC__
- __asm__ __volatile__( "fnsave %0; fwait" : "=m" (context->FloatSave) );
-# endif /* __GNUC__ */
-#endif /* __i386__ */
-}
-
-
-/***********************************************************************
- * EXC_RestoreFPU
- *
- * Restore the FPU context to a sigcontext.
- */
-static void inline EXC_RestoreFPU( CONTEXT *context, const SIGCONTEXT *sigcontext )
-{
-#ifdef __i386__
-# ifdef FPU_sig
- if (FPU_sig(sigcontext))
- {
- *FPU_sig(sigcontext) = context->FloatSave;
- return;
- }
-# endif /* FPU_sig */
-# ifdef __GNUC__
- /* avoid nested exceptions */
- context->FloatSave.StatusWord &= context->FloatSave.ControlWord | 0xffffff80;
- __asm__ __volatile__( "frstor %0; fwait" : : "m" (context->FloatSave) );
-# endif /* __GNUC__ */
-#endif /* __i386__ */
-}
-
-
-/**********************************************************************
- * EXC_GetFPUCode
- *
- * Get the FPU exception code from the FPU status.
- */
-static inline DWORD EXC_GetFPUCode( const CONTEXT *context )
-{
-#ifdef __i386__
- DWORD status = context->FloatSave.StatusWord;
-
- if (status & 0x01) /* IE */
- {
- if (status & 0x40) /* SF */
- return EXCEPTION_FLT_STACK_CHECK;
- else
- return EXCEPTION_FLT_INVALID_OPERATION;
- }
- if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND; /* DE flag */
- if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO; /* ZE flag */
- if (status & 0x08) return EXCEPTION_FLT_OVERFLOW; /* OE flag */
- if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW; /* UE flag */
- if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT; /* PE flag */
-#endif /* __i386__ */
- return EXCEPTION_FLT_INVALID_OPERATION; /* generic error */
-}
-
-
-/**********************************************************************
- * EXC_fpe
- *
- * Handler for SIGFPE.
- */
-static HANDLER_DEF(EXC_fpe)
-{
- EXCEPTION_RECORD rec;
- CONTEXT context;
-
- HANDLER_INIT();
-
- EXC_SaveFPU( &context, HANDLER_CONTEXT );
-
-#ifdef TRAP_sig
- switch(TRAP_sig(HANDLER_CONTEXT))
- {
- case 0: /* Division by zero exception */
- rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
- break;
- case 9: /* Coprocessor segment overrun */
- rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
- break;
- case 16: /* Floating point exception */
- rec.ExceptionCode = EXC_GetFPUCode( &context );
- break;
- default:
- ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
- rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
- break;
- }
-#else /* TRAP_sig */
- rec.ExceptionCode = EXC_GetFPUCode( &context );
-#endif /* TRAP_sig */
-
- EXC_SaveContext( &context, HANDLER_CONTEXT );
- rec.ExceptionFlags = 0;
- rec.ExceptionRecord = NULL;
- rec.ExceptionAddress = GET_IP(&context);
- rec.NumberParameters = 0;
- REGS_FUNC(RtlRaiseException)( &rec, &context );
- EXC_RestoreContext( &context, HANDLER_CONTEXT );
- EXC_RestoreFPU( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- * EXC_int
- *
- * Handler for SIGINT.
- */
-static HANDLER_DEF(EXC_int)
-{
- EXCEPTION_RECORD rec;
- CONTEXT context;
-
- HANDLER_INIT();
-
- EXC_SaveContext( &context, HANDLER_CONTEXT );
- rec.ExceptionCode = CONTROL_C_EXIT;
- rec.ExceptionFlags = 0;
- rec.ExceptionRecord = NULL;
- rec.ExceptionAddress = GET_IP(&context);
- rec.NumberParameters = 0;
- REGS_FUNC(RtlRaiseException)( &rec, &context );
- EXC_RestoreContext( &context, HANDLER_CONTEXT );
-}
-
-
-/**********************************************************************
- * EXC_InitHandlers
- *
- * Initialize the signal handlers for exception handling.
- */
-void EXC_InitHandlers(void)
-{
- SIGNAL_SetHandler( SIGINT, (void (*)())EXC_int );
- SIGNAL_SetHandler( SIGFPE, (void (*)())EXC_fpe );
- SIGNAL_SetHandler( SIGSEGV, (void (*)())EXC_segv );
- SIGNAL_SetHandler( SIGILL, (void (*)())EXC_segv );
-#ifdef SIGBUS
- SIGNAL_SetHandler( SIGBUS, (void (*)())EXC_segv );
-#endif
-#ifdef SIGTRAP
- SIGNAL_SetHandler( SIGTRAP, (void (*)())EXC_trap );
-#endif
- return;
-}
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
new file mode 100644
index 0000000..37e7563
--- /dev/null
+++ b/dlls/ntdll/signal_i386.c
@@ -0,0 +1,680 @@
+/*
+ * i386 signal handling routines
+ *
+ * Copyright 1999 Alexandre Julliard
+ */
+
+#ifdef __i386__
+
+#include "config.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYSCALL_H
+# include <syscall.h>
+#else
+# ifdef HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+# endif
+#endif
+
+#include "winnt.h"
+#include "stackframe.h"
+#include "global.h"
+#include "miscemu.h"
+#include "ntddk.h"
+#include "syslevel.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(seh)
+
+/***********************************************************************
+ * signal context platform-specific definitions
+ */
+
+#ifdef linux
+typedef struct
+{
+ unsigned short sc_gs, __gsh;
+ unsigned short sc_fs, __fsh;
+ unsigned short sc_es, __esh;
+ unsigned short sc_ds, __dsh;
+ unsigned long sc_edi;
+ unsigned long sc_esi;
+ unsigned long sc_ebp;
+ unsigned long sc_esp;
+ unsigned long sc_ebx;
+ unsigned long sc_edx;
+ unsigned long sc_ecx;
+ unsigned long sc_eax;
+ unsigned long sc_trapno;
+ unsigned long sc_err;
+ unsigned long sc_eip;
+ unsigned short sc_cs, __csh;
+ unsigned long sc_eflags;
+ unsigned long esp_at_signal;
+ unsigned short sc_ss, __ssh;
+ unsigned long i387;
+ unsigned long oldmask;
+ unsigned long cr2;
+} SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, SIGCONTEXT __context )
+#define HANDLER_CONTEXT (&__context)
+
+/* this is the sigaction structure from the Linux 2.1.20 kernel. */
+#undef sa_handler
+struct kernel_sigaction
+{
+ void (*sa_handler)();
+ unsigned long sa_mask;
+ unsigned long sa_flags;
+ void *sa_restorer;
+};
+
+/* Similar to the sigaction function in libc, except it leaves alone the
+ restorer field, which is used to specify the signal stack address */
+static inline int wine_sigaction( int sig, struct kernel_sigaction *new,
+ struct kernel_sigaction *old )
+{
+ __asm__ __volatile__( "pushl %%ebx\n\t"
+ "movl %2,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ : "=a" (sig)
+ : "0" (SYS_sigaction), "r" (sig), "c" (new), "d" (old) );
+ if (sig>=0) return 0;
+ errno = -sig;
+ return -1;
+}
+
+#endif /* linux */
+
+#ifdef BSDI
+
+#define EAX_sig(context) ((context)->tf_eax)
+#define EBX_sig(context) ((context)->tf_ebx)
+#define ECX_sig(context) ((context)->tf_ecx)
+#define EDX_sig(context) ((context)->tf_edx)
+#define ESI_sig(context) ((context)->tf_esi)
+#define EDI_sig(context) ((context)->tf_edi)
+#define EBP_sig(context) ((context)->tf_ebp)
+
+#define CS_sig(context) ((context)->tf_cs)
+#define DS_sig(context) ((context)->tf_ds)
+#define ES_sig(context) ((context)->tf_es)
+#define SS_sig(context) ((context)->tf_ss)
+
+#include <machine/frame.h>
+typedef struct trapframe SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, int code, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#define EFL_sig(context) ((context)->tf_eflags)
+
+#define EIP_sig(context) (*((unsigned long*)&(context)->tf_eip))
+#define ESP_sig(context) (*((unsigned long*)&(context)->tf_esp))
+
+#endif /* bsdi */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+
+#include <signal.h>
+typedef struct sigcontext SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, int code, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#endif /* FreeBSD */
+
+#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
+
+#include <signal.h>
+#ifdef _SCO_DS
+#include <sys/regset.h>
+#endif
+/* Solaris kludge */
+#undef ERR
+#include <sys/ucontext.h>
+#undef ERR
+typedef struct ucontext SIGCONTEXT;
+
+#define HANDLER_DEF(name) void name( int __signal, void *__siginfo, SIGCONTEXT *__context )
+#define HANDLER_CONTEXT __context
+
+#endif /* svr4 || SCO_DS */
+
+#ifdef __EMX__
+
+typedef struct
+{
+ unsigned long ContextFlags;
+ FLOATING_SAVE_AREA sc_float;
+ unsigned long sc_gs;
+ unsigned long sc_fs;
+ unsigned long sc_es;
+ unsigned long sc_ds;
+ unsigned long sc_edi;
+ unsigned long sc_esi;
+ unsigned long sc_eax;
+ unsigned long sc_ebx;
+ unsigned long sc_ecx;
+ unsigned long sc_edx;
+ unsigned long sc_ebp;
+ unsigned long sc_eip;
+ unsigned long sc_cs;
+ unsigned long sc_eflags;
+ unsigned long sc_esp;
+ unsigned long sc_ss;
+} SIGCONTEXT;
+
+#endif /* __EMX__ */
+
+
+#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__) \
+ || defined(__OpenBSD__) || defined(__EMX__)
+
+#define EAX_sig(context) ((context)->sc_eax)
+#define EBX_sig(context) ((context)->sc_ebx)
+#define ECX_sig(context) ((context)->sc_ecx)
+#define EDX_sig(context) ((context)->sc_edx)
+#define ESI_sig(context) ((context)->sc_esi)
+#define EDI_sig(context) ((context)->sc_edi)
+#define EBP_sig(context) ((context)->sc_ebp)
+
+#define CS_sig(context) ((context)->sc_cs)
+#define DS_sig(context) ((context)->sc_ds)
+#define ES_sig(context) ((context)->sc_es)
+#define SS_sig(context) ((context)->sc_ss)
+
+#ifdef linux
+/* FS and GS are now in the sigcontext struct of FreeBSD, but not
+ * saved by the exception handling. duh.
+ */
+#define FS_sig(context) ((context)->sc_fs)
+#define GS_sig(context) ((context)->sc_gs)
+#define CR2_sig(context) ((context)->cr2)
+#define TRAP_sig(context) ((context)->sc_trapno)
+#define ERROR_sig(context) ((context)->sc_err)
+#define FPU_sig(context) ((FLOATING_SAVE_AREA*)((context)->i387))
+#endif
+
+#ifndef __FreeBSD__
+#define EFL_sig(context) ((context)->sc_eflags)
+#else
+#define EFL_sig(context) ((context)->sc_efl)
+/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge */
+#define CR2_sig(context) ((context)->sc_err)
+#endif
+
+#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
+#define ESP_sig(context) (*((unsigned long*)&(context)->sc_esp))
+
+#endif /* linux || __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
+
+#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
+
+#ifdef _SCO_DS
+#define gregs regs
+#endif
+
+#define EAX_sig(context) ((context)->uc_mcontext.gregs[EAX])
+#define EBX_sig(context) ((context)->uc_mcontext.gregs[EBX])
+#define ECX_sig(context) ((context)->uc_mcontext.gregs[ECX])
+#define EDX_sig(context) ((context)->uc_mcontext.gregs[EDX])
+#define ESI_sig(context) ((context)->uc_mcontext.gregs[ESI])
+#define EDI_sig(context) ((context)->uc_mcontext.gregs[EDI])
+#define EBP_sig(context) ((context)->uc_mcontext.gregs[EBP])
+
+#define CS_sig(context) ((context)->uc_mcontext.gregs[CS])
+#define DS_sig(context) ((context)->uc_mcontext.gregs[DS])
+#define ES_sig(context) ((context)->uc_mcontext.gregs[ES])
+#define SS_sig(context) ((context)->uc_mcontext.gregs[SS])
+
+#define FS_sig(context) ((context)->uc_mcontext.gregs[FS])
+#define GS_sig(context) ((context)->uc_mcontext.gregs[GS])
+
+#define EFL_sig(context) ((context)->uc_mcontext.gregs[EFL])
+
+#define EIP_sig(context) ((context)->uc_mcontext.gregs[EIP])
+#ifdef R_ESP
+#define ESP_sig(context) ((context)->uc_mcontext.gregs[R_ESP])
+#else
+#define ESP_sig(context) ((context)->uc_mcontext.gregs[ESP])
+#endif
+#ifdef TRAPNO
+#define TRAP_sig(context) ((context)->uc_mcontext.gregs[TRAPNO])
+#endif
+
+#endif /* svr4 || SCO_DS */
+
+
+extern void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *context );
+
+
+/***********************************************************************
+ * handler_init
+ *
+ * Initialization code for a signal handler.
+ * Restores the proper %fs value for the current thread.
+ */
+static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+ WORD fs;
+ /* get %fs at time of the fault */
+#ifdef FS_sig
+ fs = FS_sig(sigcontext);
+#else
+ GET_FS(fs);
+#endif
+ context->SegFs = fs;
+ /* now restore a proper %fs for the fault handler */
+ if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext))) fs = SYSLEVEL_Win16CurrentTeb;
+ if (!fs) fs = SYSLEVEL_EmergencyTeb;
+ SET_FS(fs);
+}
+
+
+/***********************************************************************
+ * save_context
+ *
+ * Set the register values from a sigcontext.
+ */
+static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+ context->Eax = EAX_sig(sigcontext);
+ context->Ebx = EBX_sig(sigcontext);
+ context->Ecx = ECX_sig(sigcontext);
+ context->Edx = EDX_sig(sigcontext);
+ context->Esi = ESI_sig(sigcontext);
+ context->Edi = EDI_sig(sigcontext);
+ context->Ebp = EBP_sig(sigcontext);
+ context->EFlags = EFL_sig(sigcontext);
+ context->Eip = EIP_sig(sigcontext);
+ context->Esp = ESP_sig(sigcontext);
+ context->SegCs = LOWORD(CS_sig(sigcontext));
+ context->SegDs = LOWORD(DS_sig(sigcontext));
+ context->SegEs = LOWORD(ES_sig(sigcontext));
+ context->SegSs = LOWORD(SS_sig(sigcontext));
+ /* %fs already handled in handler_init */
+#ifdef GS_sig
+ context->SegGs = LOWORD(GS_sig(sigcontext));
+#else
+ GET_GS( context->SegGs );
+ context->SegGs &= 0xffff;
+#endif
+ if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
+}
+
+
+/***********************************************************************
+ * restore_context
+ *
+ * Build a sigcontext from the register values.
+ */
+static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
+{
+ EAX_sig(sigcontext) = context->Eax;
+ EBX_sig(sigcontext) = context->Ebx;
+ ECX_sig(sigcontext) = context->Ecx;
+ EDX_sig(sigcontext) = context->Edx;
+ ESI_sig(sigcontext) = context->Esi;
+ EDI_sig(sigcontext) = context->Edi;
+ EBP_sig(sigcontext) = context->Ebp;
+ EFL_sig(sigcontext) = context->EFlags;
+ EIP_sig(sigcontext) = context->Eip;
+ ESP_sig(sigcontext) = context->Esp;
+ CS_sig(sigcontext) = context->SegCs;
+ DS_sig(sigcontext) = context->SegDs;
+ ES_sig(sigcontext) = context->SegEs;
+ SS_sig(sigcontext) = context->SegSs;
+#ifdef FS_sig
+ FS_sig(sigcontext) = context->SegFs;
+#else
+ SET_FS( context->SegFs );
+#endif
+#ifdef GS_sig
+ GS_sig(sigcontext) = context->SegGs;
+#else
+ SET_GS( context->SegGs );
+#endif
+}
+
+
+/***********************************************************************
+ * save_fpu
+ *
+ * Set the FPU context from a sigcontext.
+ */
+static void inline save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+#ifdef FPU_sig
+ if (FPU_sig(sigcontext))
+ {
+ context->FloatSave = *FPU_sig(sigcontext);
+ return;
+ }
+#endif /* FPU_sig */
+#ifdef __GNUC__
+ __asm__ __volatile__( "fnsave %0; fwait" : "=m" (context->FloatSave) );
+#endif /* __GNUC__ */
+}
+
+
+/***********************************************************************
+ * restore_fpu
+ *
+ * Restore the FPU context to a sigcontext.
+ */
+static void inline restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
+{
+#ifdef FPU_sig
+ if (FPU_sig(sigcontext))
+ {
+ *FPU_sig(sigcontext) = context->FloatSave;
+ return;
+ }
+#endif /* FPU_sig */
+#ifdef __GNUC__
+ /* avoid nested exceptions */
+ context->FloatSave.StatusWord &= context->FloatSave.ControlWord | 0xffffff80;
+ __asm__ __volatile__( "frstor %0; fwait" : : "m" (context->FloatSave) );
+#endif /* __GNUC__ */
+}
+
+
+/**********************************************************************
+ * get_fpu_code
+ *
+ * Get the FPU exception code from the FPU status.
+ */
+static inline DWORD get_fpu_code( const CONTEXT *context )
+{
+ DWORD status = context->FloatSave.StatusWord;
+
+ if (status & 0x01) /* IE */
+ {
+ if (status & 0x40) /* SF */
+ return EXCEPTION_FLT_STACK_CHECK;
+ else
+ return EXCEPTION_FLT_INVALID_OPERATION;
+ }
+ if (status & 0x02) return EXCEPTION_FLT_DENORMAL_OPERAND; /* DE flag */
+ if (status & 0x04) return EXCEPTION_FLT_DIVIDE_BY_ZERO; /* ZE flag */
+ if (status & 0x08) return EXCEPTION_FLT_OVERFLOW; /* OE flag */
+ if (status & 0x10) return EXCEPTION_FLT_UNDERFLOW; /* UE flag */
+ if (status & 0x20) return EXCEPTION_FLT_INEXACT_RESULT; /* PE flag */
+ return EXCEPTION_FLT_INVALID_OPERATION; /* generic error */
+}
+
+
+/**********************************************************************
+ * segv_handler
+ *
+ * Handler for SIGSEGV and related errors.
+ */
+static HANDLER_DEF(segv_handler)
+{
+ EXCEPTION_RECORD rec;
+ CONTEXT context;
+
+ handler_init( &context, HANDLER_CONTEXT );
+
+#if defined(TRAP_sig) && defined(CR2_sig)
+ /* we want the page-fault case to be fast */
+ if (TRAP_sig(HANDLER_CONTEXT) == 14)
+ if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return;
+#endif
+
+ save_context( &context, HANDLER_CONTEXT );
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
+ rec.ExceptionAddress = (LPVOID)context.Eip;
+ rec.NumberParameters = 0;
+
+#ifdef TRAP_sig
+ switch(TRAP_sig(HANDLER_CONTEXT))
+ {
+ case 4: /* Overflow exception */
+ rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
+ break;
+ case 5: /* Bound range exception */
+ rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+ break;
+ case 6: /* Invalid opcode exception */
+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+ break;
+ case 12: /* Stack fault */
+ rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+ break;
+ case 11: /* Segment not present exception */
+ case 13: /* General protection fault */
+ if (INSTR_EmulateInstruction( &context )) goto restore;
+ rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+ break;
+ case 14: /* Page fault */
+#ifdef CR2_sig
+ rec.NumberParameters = 2;
+#ifdef ERROR_sig
+ rec.ExceptionInformation[0] = (ERROR_sig(HANDLER_CONTEXT) & 2) != 0;
+#else
+ rec.ExceptionInformation[0] = 0;
+#endif /* ERROR_sig */
+ rec.ExceptionInformation[1] = CR2_sig(HANDLER_CONTEXT);
+#endif /* CR2_sig */
+ rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+ break;
+ case 17: /* Alignment check exception */
+ /* FIXME: pass through exception handler first? */
+ if (context.EFlags & 0x00040000)
+ {
+ /* Disable AC flag, return */
+ context.EFlags &= ~0x00040000;
+ goto restore;
+ }
+ rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+ break;
+ default:
+ ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
+ /* fall through */
+ case 2: /* NMI interrupt */
+ case 7: /* Device not available exception */
+ case 8: /* Double fault exception */
+ case 10: /* Invalid TSS exception */
+ case 15: /* Unknown exception */
+ case 18: /* Machine check exception */
+ case 19: /* Cache flush exception */
+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+ break;
+ }
+#else /* TRAP_sig */
+ if (INSTR_EmulateInstruction( &context )) return;
+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; /* generic error */
+#endif /* TRAP_sig */
+
+ REGS_FUNC(RtlRaiseException)( &rec, &context );
+ restore:
+ restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ * trap_handler
+ *
+ * Handler for SIGTRAP.
+ */
+static HANDLER_DEF(trap_handler)
+{
+ EXCEPTION_RECORD rec;
+ CONTEXT context;
+
+ handler_init( &context, HANDLER_CONTEXT );
+
+#ifdef TRAP_sig
+ rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ?
+ EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT;
+#else
+ rec.ExceptionCode = EXCEPTION_BREAKPOINT;
+#endif /* TRAP_sig */
+
+ save_context( &context, HANDLER_CONTEXT );
+ rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = (LPVOID)context.Eip;
+ rec.NumberParameters = 0;
+ REGS_FUNC(RtlRaiseException)( &rec, &context );
+ restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ * fpe_handler
+ *
+ * Handler for SIGFPE.
+ */
+static HANDLER_DEF(fpe_handler)
+{
+ EXCEPTION_RECORD rec;
+ CONTEXT context;
+
+ handler_init( &context, HANDLER_CONTEXT );
+
+ save_fpu( &context, HANDLER_CONTEXT );
+
+#ifdef TRAP_sig
+ switch(TRAP_sig(HANDLER_CONTEXT))
+ {
+ case 0: /* Division by zero exception */
+ rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+ break;
+ case 9: /* Coprocessor segment overrun */
+ rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+ break;
+ case 16: /* Floating point exception */
+ rec.ExceptionCode = get_fpu_code( &context );
+ break;
+ default:
+ ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
+ rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+ break;
+ }
+#else /* TRAP_sig */
+ rec.ExceptionCode = get_fpu_code( &context );
+#endif /* TRAP_sig */
+
+ save_context( &context, HANDLER_CONTEXT );
+ rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = (LPVOID)context.Eip;
+ rec.NumberParameters = 0;
+ REGS_FUNC(RtlRaiseException)( &rec, &context );
+ restore_context( &context, HANDLER_CONTEXT );
+ restore_fpu( &context, HANDLER_CONTEXT );
+}
+
+
+/**********************************************************************
+ * int_handler
+ *
+ * Handler for SIGINT.
+ */
+static HANDLER_DEF(int_handler)
+{
+ EXCEPTION_RECORD rec;
+ CONTEXT context;
+
+ handler_init( &context, HANDLER_CONTEXT );
+ save_context( &context, HANDLER_CONTEXT );
+ rec.ExceptionCode = CONTROL_C_EXIT;
+ rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = (LPVOID)context.Eip;
+ rec.NumberParameters = 0;
+ REGS_FUNC(RtlRaiseException)( &rec, &context );
+ restore_context( &context, HANDLER_CONTEXT );
+}
+
+
+/***********************************************************************
+ * set_handler
+ *
+ * Set a signal handler
+ */
+static int set_handler( int sig, void (*func)() )
+{
+#ifdef linux
+ struct kernel_sigaction sig_act;
+ sig_act.sa_handler = func;
+ sig_act.sa_flags = SA_RESTART | SA_NOMASK;
+ sig_act.sa_mask = 0;
+ /* point to the top of the stack */
+ sig_act.sa_restorer = (char *)NtCurrentTeb()->signal_stack + SIGNAL_STACK_SIZE;
+ return wine_sigaction( sig, &sig_act, NULL );
+#else /* linux */
+ struct sigaction sig_act;
+ sig_act.sa_handler = func;
+ sigemptyset( &sig_act.sa_mask );
+
+# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ sig_act.sa_flags = SA_ONSTACK;
+# elif defined (__svr4__) || defined(_SCO_DS)
+ sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
+# elif defined(__EMX__)
+ sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
+# else
+ sig_act.sa_flags = 0;
+# endif
+ return sigaction( sig, &sig_act, NULL );
+#endif /* linux */
+}
+
+
+/**********************************************************************
+ * SIGNAL_Init
+ */
+BOOL SIGNAL_Init(void)
+{
+#ifdef HAVE_WORKING_SIGALTSTACK
+ struct sigaltstack ss;
+ if ((ss.ss_sp = NtCurrentTeb()->signal_stack))
+ {
+ ss.ss_size = SIGNAL_STACK_SIZE;
+ ss.ss_flags = 0;
+ if (sigaltstack(&ss, NULL) < 0)
+ {
+ perror("sigaltstack");
+ /* fall through on error and try it differently */
+ }
+ }
+#endif /* HAVE_SIGALTSTACK */
+
+ /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
+ signal( SIGPIPE, SIG_IGN );
+ /* automatic child reaping to avoid zombies */
+ signal( SIGCHLD, SIG_IGN );
+
+ if (set_handler( SIGINT, (void (*)())int_handler ) == -1) goto error;
+ if (set_handler( SIGFPE, (void (*)())fpe_handler ) == -1) goto error;
+ if (set_handler( SIGSEGV, (void (*)())segv_handler ) == -1) goto error;
+ if (set_handler( SIGILL, (void (*)())segv_handler ) == -1) goto error;
+#ifdef SIGBUS
+ if (set_handler( SIGBUS, (void (*)())segv_handler ) == -1) goto error;
+#endif
+#ifdef SIGTRAP
+ if (set_handler( SIGTRAP, (void (*)())trap_handler ) == -1) goto error;
+#endif
+ return TRUE;
+
+ error:
+ perror("sigaction");
+ return FALSE;
+}
+
+#endif /* __i386__ */
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 45a4534..853bef0 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -3516,7 +3516,7 @@
TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
#ifdef RESTORE_SIGNALS
- EXC_InitHandlers();
+ SIGNAL_Init();
#endif
return DD_OK;
}
@@ -3918,7 +3918,7 @@
Sleep(1000);
TSXF86DGADirectVideo(display,DefaultScreen(display),0);
#ifdef RESTORE_SIGNALS
- EXC_InitHandlers();
+ SIGNAL_Init();
#endif
return DD_OK;
}
@@ -3969,7 +3969,7 @@
#endif
#ifdef RESTORE_SIGNALS
- EXC_InitHandlers();
+ SIGNAL_Init();
#endif
HeapFree(GetProcessHeap(),0,This);
return 0;
@@ -4958,7 +4958,7 @@
depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
_common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
#ifdef RESTORE_SIGNALS
- EXC_InitHandlers();
+ SIGNAL_Init();
#endif
return DD_OK;
diff --git a/include/debugger.h b/include/debugger.h
index fd11fda..bcbded2 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -9,7 +9,6 @@
#include <sys/types.h> /* u_long ... */
#include "windef.h"
-#include "sig_context.h"
#include "miscemu.h"
#define STEP_FLAG 0x100 /* single step flag */
diff --git a/include/dosexe.h b/include/dosexe.h
index 9c27003..f8e365f 100644
--- a/include/dosexe.h
+++ b/include/dosexe.h
@@ -10,7 +10,6 @@
#include <sys/types.h> /* pid_t */
#include "winbase.h" /* for LPSTARTUPINFO32A */
#include "winnt.h" /* for PCONTEXT */
-#include "sig_context.h"
typedef struct _DOSSYSTEM {
int id;
diff --git a/include/miscemu.h b/include/miscemu.h
index d6648a6..c91bb59 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -184,10 +184,6 @@
/* msdos/xms.c */
extern void WINAPI XMS_Handler(CONTEXT86*);
-/* loader/signal.c */
-extern BOOL SIGNAL_Init(void);
-extern void SIGNAL_SetHandler( int sig, void (*func)() );
-
/* misc/aspi.c */
extern void ASPI_DOS_HandleInt(CONTEXT86 *context);
diff --git a/include/sig_context.h b/include/sig_context.h
deleted file mode 100644
index 393e0c2..0000000
--- a/include/sig_context.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Signal context definitions
- *
- * Copyright 1995 Alexandre Julliard
- */
-
-#ifndef __WINE_SIG_CONTEXT_H
-#define __WINE_SIG_CONTEXT_H
-
-#ifdef __i386__
-
-#ifdef linux
-typedef struct
-{
- unsigned short sc_gs, __gsh;
- unsigned short sc_fs, __fsh;
- unsigned short sc_es, __esh;
- unsigned short sc_ds, __dsh;
- unsigned long sc_edi;
- unsigned long sc_esi;
- unsigned long sc_ebp;
- unsigned long sc_esp;
- unsigned long sc_ebx;
- unsigned long sc_edx;
- unsigned long sc_ecx;
- unsigned long sc_eax;
- unsigned long sc_trapno;
- unsigned long sc_err;
- unsigned long sc_eip;
- unsigned short sc_cs, __csh;
- unsigned long sc_eflags;
- unsigned long esp_at_signal;
- unsigned short sc_ss, __ssh;
- unsigned long i387;
- unsigned long oldmask;
- unsigned long cr2;
-} SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name (int signal, SIGCONTEXT __context)
-#define HANDLER_CONTEXT (&__context)
-
-#endif /* linux */
-
-#ifdef BSDI
-
-#define EAX_sig(context) ((context)->tf_eax)
-#define EBX_sig(context) ((context)->tf_ebx)
-#define ECX_sig(context) ((context)->tf_ecx)
-#define EDX_sig(context) ((context)->tf_edx)
-#define ESI_sig(context) ((context)->tf_esi)
-#define EDI_sig(context) ((context)->tf_edi)
-#define EBP_sig(context) ((context)->tf_ebp)
-
-#define CS_sig(context) ((context)->tf_cs)
-#define DS_sig(context) ((context)->tf_ds)
-#define ES_sig(context) ((context)->tf_es)
-#define SS_sig(context) ((context)->tf_ss)
-
-#include <machine/frame.h>
-typedef struct trapframe SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, int code, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#define EFL_sig(context) ((context)->tf_eflags)
-
-#define EIP_sig(context) (*((unsigned long*)&(context)->tf_eip))
-#define ESP_sig(context) (*((unsigned long*)&(context)->tf_esp))
-
-#endif /* bsdi */
-
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-
-#include <signal.h>
-typedef struct sigcontext SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, int code, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#endif /* FreeBSD */
-
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
-
-#include <signal.h>
-#ifdef _SCO_DS
-#include <sys/regset.h>
-#endif
-/* Solaris kludge */
-#undef ERR
-#include <sys/ucontext.h>
-#undef ERR
-typedef struct ucontext SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-
-#define HANDLER_DEF(name) void name(int signal, void *siginfo, SIGCONTEXT *__context)
-#define HANDLER_CONTEXT __context
-
-#endif /* svr4 || SCO_DS */
-
-#ifdef __EMX__
-typedef struct _fpreg /* Note 1 */
-{
- ULONG losig;
- ULONG hisig;
- USHORT signexp;
-} FPREG;
-typedef FPREG *PFPREG;
-
-typedef struct _CONTEXT /* Note 1 */
-{
- ULONG ContextFlags;
- ULONG ctx_env[7];
- FPREG ctx_stack[8];
- ULONG ctx_SegGs;
- ULONG ctx_SegFs;
- ULONG ctx_SegEs;
- ULONG ctx_SegDs;
- ULONG ctx_RegEdi;
- ULONG ctx_RegEsi;
- ULONG ctx_RegEax;
- ULONG ctx_RegEbx;
- ULONG ctx_RegEcx;
- ULONG ctx_RegEdx;
- ULONG ctx_RegEbp;
- ULONG ctx_RegEip;
- ULONG ctx_SegCs;
- ULONG ctx_EFlags;
- ULONG ctx_RegEsp;
- ULONG ctx_SegSs;
-} SIGCONTEXT;
-#define __HAVE_SIGCONTEXT
-/*typedef CONTEXTRECORD *PCONTEXTRECORD;*/
-
-#endif /* __EMX__ */
-
-
-#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__) \
- || defined(__OpenBSD__)
-
-#define EAX_sig(context) ((context)->sc_eax)
-#define EBX_sig(context) ((context)->sc_ebx)
-#define ECX_sig(context) ((context)->sc_ecx)
-#define EDX_sig(context) ((context)->sc_edx)
-#define ESI_sig(context) ((context)->sc_esi)
-#define EDI_sig(context) ((context)->sc_edi)
-#define EBP_sig(context) ((context)->sc_ebp)
-
-#define CS_sig(context) ((context)->sc_cs)
-#define DS_sig(context) ((context)->sc_ds)
-#define ES_sig(context) ((context)->sc_es)
-#define SS_sig(context) ((context)->sc_ss)
-
-#ifdef linux
-/* FS and GS are now in the sigcontext struct of FreeBSD, but not
- * saved by the exception handling. duh.
- */
-#define FS_sig(context) ((context)->sc_fs)
-#define GS_sig(context) ((context)->sc_gs)
-#define CR2_sig(context) ((context)->cr2)
-#define TRAP_sig(context) ((context)->sc_trapno)
-#define ERROR_sig(context) ((context)->sc_err)
-#define FPU_sig(context) ((FLOATING_SAVE_AREA*)((context)->i387))
-#endif
-
-#ifndef __FreeBSD__
-#define EFL_sig(context) ((context)->sc_eflags)
-#else
-#define EFL_sig(context) ((context)->sc_efl)
-/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge */
-#define CR2_sig(context) ((context)->sc_err)
-#endif
-
-
-#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
-#define ESP_sig(context) (*((unsigned long*)&(context)->sc_esp))
-
-#endif /* linux || __NetBSD__ || __FreeBSD__ || __OpenBSD__ */
-
-#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
-
-#ifdef _SCO_DS
-#define gregs regs
-#endif
-
-#define EAX_sig(context) ((context)->uc_mcontext.gregs[EAX])
-#define EBX_sig(context) ((context)->uc_mcontext.gregs[EBX])
-#define ECX_sig(context) ((context)->uc_mcontext.gregs[ECX])
-#define EDX_sig(context) ((context)->uc_mcontext.gregs[EDX])
-#define ESI_sig(context) ((context)->uc_mcontext.gregs[ESI])
-#define EDI_sig(context) ((context)->uc_mcontext.gregs[EDI])
-#define EBP_sig(context) ((context)->uc_mcontext.gregs[EBP])
-
-#define CS_sig(context) ((context)->uc_mcontext.gregs[CS])
-#define DS_sig(context) ((context)->uc_mcontext.gregs[DS])
-#define ES_sig(context) ((context)->uc_mcontext.gregs[ES])
-#define SS_sig(context) ((context)->uc_mcontext.gregs[SS])
-
-#define FS_sig(context) ((context)->uc_mcontext.gregs[FS])
-#define GS_sig(context) ((context)->uc_mcontext.gregs[GS])
-
-#define EFL_sig(context) ((context)->uc_mcontext.gregs[EFL])
-
-#define EIP_sig(context) ((context)->uc_mcontext.gregs[EIP])
-#ifdef R_ESP
-#define ESP_sig(context) ((context)->uc_mcontext.gregs[R_ESP])
-#else
-#define ESP_sig(context) ((context)->uc_mcontext.gregs[ESP])
-#endif
-#ifdef TRAPNO
-#define TRAP_sig(context) ((context)->uc_mcontext.gregs[TRAPNO])
-#endif
-
-#endif /* svr4 || SCO_DS */
-
-#ifdef __EMX__
-
-#define EAX_sig(context) ((context)->ctx_RegEax)
-#define EBX_sig(context) ((context)->ctx_RegEbx)
-#define ECX_sig(context) ((context)->ctx_RegEcx)
-#define EDX_sig(context) ((context)->ctx_RegEdx)
-#define ESI_sig(context) ((context)->ctx_RegEsi)
-#define EDI_sig(context) ((context)->ctx_RegEdi)
-#define EBP_sig(context) ((context)->ctx_RegEbp)
-#define ESP_sig(context) ((context)->ctx_RegEsp)
-#define CS_sig(context) ((context)->ctx_SegCs)
-#define DS_sig(context) ((context)->ctx_SegDs)
-#define ES_sig(context) ((context)->ctx_SegEs)
-#define SS_sig(context) ((context)->ctx_SegSs)
-#define FS_sig(context) ((context)->ctx_SegFs)
-#define GS_sig(context) ((context)->ctx_SegGs)
-#define EFL_sig(context) ((context)->ctx_EFlags)
-#define EIP_sig(context) ((context)->ctx_RegEip)
-
-#endif /* __EMX__ */
-
-#ifdef FS_sig
-#include "syslevel.h"
-#define HANDLER_INIT() \
- do { int fs = IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)) ? \
- FS_sig(HANDLER_CONTEXT) : SYSLEVEL_Win16CurrentTeb; \
- if (!fs) fs = SYSLEVEL_EmergencyTeb; \
- SET_FS(fs); } while (0)
-#else
-#define HANDLER_INIT() \
- do { int fs; GET_FS(fs); fs &= 0xffff; \
- if (!IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT))) \
- fs = SYSLEVEL_Win16CurrentTeb; \
- if (!fs) fs = SYSLEVEL_EmergencyTeb; \
- SET_FS(fs); } while (0)
-#endif
-
-#else /* __i386__ */
-
-#define HANDLER_DEF(name) void name (int signal)
-#define HANDLER_INIT() /* nothing */
-
-#endif /* __i386__ */
-
-#ifndef __HAVE_SIGCONTEXT
-/* empty entry for non x86 architectures mostly. */
-typedef DWORD SIGCONTEXT;
-#define HANDLER_CONTEXT 0
-#endif
-
-#endif /* __WINE_SIG_CONTEXT_H */
diff --git a/include/wine/exception.h b/include/wine/exception.h
index caa20b8..79c437a 100644
--- a/include/wine/exception.h
+++ b/include/wine/exception.h
@@ -169,7 +169,7 @@
typedef DWORD (*DEBUGHOOK)( EXCEPTION_RECORD *, CONTEXT *, BOOL );
extern void EXC_SetDebugEventHook( DEBUGHOOK hook );
extern DEBUGHOOK EXC_GetDebugEventHook(void);
-extern void EXC_InitHandlers(void);
+extern BOOL SIGNAL_Init(void);
#endif
#endif /* __WINE_WINE_EXCEPTION_H */
diff --git a/loader/Makefile.in b/loader/Makefile.in
index 448f984..67d1bd8 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -15,7 +15,6 @@
pe_image.c \
pe_resource.c \
resource.c \
- signal.c \
task.c
GLUE = task.c
diff --git a/loader/main.c b/loader/main.c
index dea1b95..a4a6815 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -65,9 +65,6 @@
/* Initialize syslevel handling */
SYSLEVEL_Init();
- /* Initialize signal handling */
- if (!SIGNAL_Init()) return FALSE;
-
/* Load the configuration file */
if (!PROFILE_LoadWineIni()) return FALSE;
diff --git a/loader/signal.c b/loader/signal.c
deleted file mode 100644
index ab67c24..0000000
--- a/loader/signal.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Wine signal handling
- *
- * Copyright 1995 Alexandre Julliard
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <setjmp.h>
-
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#ifdef HAVE_SYSCALL_H
-# include <syscall.h>
-#else
-# ifdef HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-# endif
-#endif
-
-#include "winsock.h"
-#include "global.h"
-#include "options.h"
-#include "miscemu.h"
-#include "dosexe.h"
-#include "thread.h"
-#include "wine/exception.h"
-#include "debugtools.h"
-
-
-/* Linux sigaction function */
-
-#if defined(linux) && defined(__i386__)
-/* This is the sigaction structure from the Linux 2.1.20 kernel. */
-
-#undef sa_handler
-struct kernel_sigaction
-{
- void (*sa_handler)();
- unsigned long sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)();
-};
-
-/* Similar to the sigaction function in libc, except it leaves alone the
- restorer field, which is used to specify the signal stack address */
-static inline int wine_sigaction( int sig, struct kernel_sigaction *new,
- struct kernel_sigaction *old )
-{
-#ifdef __PIC__
- __asm__ __volatile__( "pushl %%ebx\n\t"
- "movl %2,%%ebx\n\t"
- "int $0x80\n\t"
- "popl %%ebx"
- : "=a" (sig)
- : "0" (SYS_sigaction),
- "r" (sig),
- "c" (new),
- "d" (old) );
-#else
- __asm__ __volatile__( "int $0x80"
- : "=a" (sig)
- : "0" (SYS_sigaction),
- "b" (sig),
- "c" (new),
- "d" (old) );
-#endif /* __PIC__ */
- if (sig>=0)
- return 0;
- errno = -sig;
- return -1;
-}
-#endif /* linux && __i386__ */
-
-/* Signal stack */
-
-static char SIGNAL_Stack[16384];
-
-
-/**********************************************************************
- * SIGNAL_SetHandler
- */
-void SIGNAL_SetHandler( int sig, void (*func)() )
-{
- int ret;
-
-#if defined(linux) && defined(__i386__)
-
- struct kernel_sigaction sig_act;
- sig_act.sa_handler = func;
- sig_act.sa_flags = SA_RESTART | SA_NOMASK;
- sig_act.sa_mask = 0;
- /* Point to the top of the stack, minus 4 just in case, and make
- it aligned */
- sig_act.sa_restorer =
- (void (*)())((int)(SIGNAL_Stack + sizeof(SIGNAL_Stack) - 4) & ~3);
- ret = wine_sigaction( sig, &sig_act, NULL );
-
-#else /* linux && __i386__ */
-
- struct sigaction sig_act;
- sig_act.sa_handler = func;
- sigemptyset( &sig_act.sa_mask );
-
-# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
- sig_act.sa_flags = SA_ONSTACK;
-# elif defined (__svr4__) || defined(_SCO_DS)
- sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
-# elif defined(__EMX__)
- sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
-# else
- sig_act.sa_flags = 0;
-# endif
- ret = sigaction( sig, &sig_act, NULL );
-
-#endif /* linux && __i386__ */
-
- if (ret < 0)
- {
- perror( "sigaction" );
- exit(1);
- }
-}
-
-
-/**********************************************************************
- * SIGNAL_Init
- */
-BOOL SIGNAL_Init(void)
-{
-#ifdef HAVE_WORKING_SIGALTSTACK
- struct sigaltstack ss;
- ss.ss_sp = SIGNAL_Stack;
- ss.ss_size = sizeof(SIGNAL_Stack);
- ss.ss_flags = 0;
- if (sigaltstack(&ss, NULL) < 0)
- {
- perror("sigaltstack");
- /* fall through on error and try it differently */
- }
-#endif /* HAVE_SIGALTSTACK */
-
- /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */
- signal (SIGPIPE, SIG_IGN);
- /* automatic child reaping to avoid zombies */
- signal (SIGCHLD, SIG_IGN);
- EXC_InitHandlers();
- return TRUE;
-}
diff --git a/scheduler/process.c b/scheduler/process.c
index db423d9..1e0bb8a 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -362,6 +362,9 @@
if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return FALSE;
initial_pdb.system_heap = initial_pdb.heap = SystemHeap;
+ /* Initialize signal handling */
+ if (!SIGNAL_Init()) return FALSE;
+
/* Create the environment DB of the first process */
if (!PROCESS_CreateEnvDB()) return FALSE;
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 6086a38..c9ea1b0 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -28,6 +28,7 @@
#include "thread.h"
#include "server.h"
#include "winbase.h"
+#include "wine/exception.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(thread)
@@ -130,7 +131,16 @@
{
SYSDEPS_SetCurThread( teb );
CLIENT_InitThread();
- teb->startup();
+ SIGNAL_Init();
+ __TRY
+ {
+ teb->startup();
+ }
+ __EXCEPT(UnhandledExceptionFilter)
+ {
+ TerminateThread( GetCurrentThread(), GetExceptionCode() );
+ }
+ __ENDTRY
SYSDEPS_ExitThread(); /* should never get here */
}