From 1eeed68514c574e0c4f2ff46fc3326dbedcc2b95 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 18 Jun 1999 18:21:24 +0000 Subject: [PATCH] Moved signal handling to exception.c, generate exceptions on signals. Added hook for debugger in exception handling (temporary). --- dlls/ntdll/exception.c | 441 ++++++++++++++++++++++++++++++++++++++++- graphics/ddraw.c | 10 +- include/miscemu.h | 1 - include/sig_context.h | 4 + loader/signal.c | 145 +------------- 5 files changed, 442 insertions(+), 159 deletions(-) diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 037947a5f82..250aa90c386 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -5,12 +5,16 @@ * Copyright 1999 Alexandre Julliard */ -#include "debugtools.h" +#include #include "winnt.h" #include "ntddk.h" #include "process.h" +#include "global.h" #include "wine/exception.h" #include "stackframe.h" +#include "sig_context.h" +#include "miscemu.h" +#include "debugtools.h" DEFAULT_DEBUG_CHANNEL(seh) @@ -21,6 +25,41 @@ typedef struct EXCEPTION_FRAME *prevFrame; } EXC_NESTED_FRAME; +#ifdef __i386__ +# define GET_IP(context) ((LPVOID)EIP_reg(context)) +#else +# define GET_IP(context) ((LPVOID)0) +#endif /* __i386__ */ + +/* Default hook for built-in debugger */ +static DWORD default_hook( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first ) +{ + if (!first) + { + DPRINTF( "stopping process due to unhandled exception %08lx.\n", + rec->ExceptionCode ); + raise( SIGSTOP ); + } + return 0; /* not handled */ +} +static DEBUGHOOK debug_hook = default_hook; + +/******************************************************************* + * EXC_SetDebugEventHook + * EXC_GetDebugEventHook + * + * Set/Get the hook for the built-in debugger. + * + * FIXME: the built-in debugger should use the normal debug events. + */ +void EXC_SetDebugEventHook( DEBUGHOOK hook ) +{ + debug_hook = hook; +} +DEBUGHOOK EXC_GetDebugEventHook(void) +{ + return debug_hook; +} /******************************************************************* * EXC_RaiseHandler @@ -90,6 +129,9 @@ static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) (DEBUG_SendExceptionEvent( rec, FALSE ) == DBG_CONTINUE)) return; /* continue execution */ + if (debug_hook( rec, context, FALSE ) == DBG_CONTINUE) + return; /* continue execution */ + if (rec->ExceptionFlags & EH_STACK_INVALID) ERR("Exception frame is not in stack limits => unable to dispatch exception.\n"); else if (rec->ExceptionCode == EXCEPTION_NONCONTINUABLE_EXCEPTION) @@ -97,7 +139,6 @@ static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context ) else ERR("Unhandled exception code %lx flags %lx addr %p\n", rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); - /* Should I add here a back trace ? */ TerminateProcess( GetCurrentProcess(), 1 ); } @@ -117,13 +158,16 @@ void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *contex (DEBUG_SendExceptionEvent( rec, TRUE ) == DBG_CONTINUE)) return; /* continue execution */ - frame = NtCurrentTeb()->except; + if (debug_hook( rec, context, TRUE ) == DBG_CONTINUE) + return; /* continue execution */ + + frame = CURRENT()->except; nested_frame = NULL; while (frame != (PEXCEPTION_FRAME)0xFFFFFFFF) { /* Check frame address */ - if (((void*)frame < NtCurrentTeb()->stack_low) || - ((void*)(frame+1) > NtCurrentTeb()->stack_top) || + if (((void*)frame < CURRENT()->stack_low) || + ((void*)(frame+1) > CURRENT()->stack_top) || (int)frame & 3) { rec->ExceptionFlags |= EH_STACK_INVALID; @@ -187,7 +231,7 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, record.ExceptionCode = STATUS_UNWIND; record.ExceptionFlags = 0; record.ExceptionRecord = NULL; - record.ExceptionAddress = (LPVOID)EIP_reg(context); + record.ExceptionAddress = GET_IP(context); record.NumberParameters = 0; pRecord = &record; } @@ -197,7 +241,7 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, TRACE( "code=%lx flags=%lx\n", pRecord->ExceptionCode, pRecord->ExceptionFlags ); /* get chain of exception frames */ - frame = NtCurrentTeb()->except; + frame = CURRENT()->except; while ((frame != (PEXCEPTION_FRAME)0xffffffff) && (frame != pEndFrame)) { /* Check frame address */ @@ -209,8 +253,8 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, newrec.NumberParameters = 0; RtlRaiseException( &newrec ); /* never returns */ } - if (((void*)frame < NtCurrentTeb()->stack_low) || - ((void*)(frame+1) > NtCurrentTeb()->stack_top) || + if (((void*)frame < CURRENT()->stack_low) || + ((void*)(frame+1) > CURRENT()->stack_top) || (int)frame & 3) { newrec.ExceptionCode = STATUS_BAD_STACK; @@ -237,7 +281,7 @@ void WINAPI REGS_FUNC(RtlUnwind)( PEXCEPTION_FRAME pEndFrame, LPVOID unusedEip, RtlRaiseException( &newrec ); /* never returns */ break; } - NtCurrentTeb()->except = frame = frame->Prev; + frame = EXC_pop_frame( frame ); } } @@ -271,3 +315,380 @@ void WINAPI RtlRaiseStatus( NTSTATUS status ) ExceptionRec.NumberParameters = 0; RtlRaiseException( &ExceptionRec ); } + + +/*********************************************************************** + * DebugBreak (KERNEL32.181) + */ +void WINAPI REGS_FUNC(DebugBreak)( CONTEXT *context ) +{ + EXCEPTION_RECORD rec; + + rec.ExceptionCode = EXCEPTION_BREAKPOINT; + rec.ExceptionFlags = EH_NONCONTINUABLE; + rec.ExceptionRecord = NULL; + rec.NumberParameters = 0; + REGS_FUNC(RtlRaiseException)( &rec, context ); +} + + +/*********************************************************************** + * DebugBreak16 (KERNEL.203) + */ +void WINAPI DebugBreak16( CONTEXT *context ) +{ + REGS_FUNC(DebugBreak)( context ); +} + + +/*********************************************************************** + * 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(); + + 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( HANDLER_CONTEXT )) return; + rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION; + break; + case 14: /* Page fault */ +#ifdef CR2_sig + if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return; + 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_sig(HANDLER_CONTEXT) & 0x00040000) + { + /* Disable AC flag, return */ + EFL_sig(HANDLER_CONTEXT) &= ~0x00040000; + return; + } + 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( HANDLER_CONTEXT )) return; +# endif + rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; /* generic error */ +#endif /* TRAP_sig */ + + EXC_SaveContext( &context, HANDLER_CONTEXT ); + rec.ExceptionRecord = NULL; + rec.ExceptionFlags = EH_NONCONTINUABLE; + rec.ExceptionAddress = GET_IP(&context); + REGS_FUNC(RtlRaiseException)( &rec, &context ); + 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 = EH_NONCONTINUABLE; + 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 = EH_NONCONTINUABLE; + 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, 1 ); + SIGNAL_SetHandler( SIGFPE, (void (*)())EXC_fpe, 1 ); + SIGNAL_SetHandler( SIGSEGV, (void (*)())EXC_segv, 1 ); + SIGNAL_SetHandler( SIGILL, (void (*)())EXC_segv, 1 ); +#ifdef SIGBUS + SIGNAL_SetHandler( SIGBUS, (void (*)())EXC_segv, 1 ); +#endif +#ifdef SIGTRAP + SIGNAL_SetHandler( SIGTRAP, (void (*)())EXC_trap, 1 ); +#endif + return; +} diff --git a/graphics/ddraw.c b/graphics/ddraw.c index a35ff4314f5..29c1a658d0a 100644 --- a/graphics/ddraw.c +++ b/graphics/ddraw.c @@ -54,7 +54,7 @@ typedef int INT32; #include "heap.h" #include "dc.h" #include "win.h" -#include "miscemu.h" +#include "wine/exception.h" #include "ddraw.h" #include "d3d.h" #include "debug.h" @@ -3384,7 +3384,7 @@ static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode( TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); #ifdef RESTORE_SIGNALS - SIGNAL_InitHandlers(); + EXC_InitHandlers(); #endif return DD_OK; #else /* defined(HAVE_LIBXXF86DGA) */ @@ -3816,7 +3816,7 @@ static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 ifac Sleep(1000); TSXF86DGADirectVideo(display,DefaultScreen(display),0); #ifdef RESTORE_SIGNALS - SIGNAL_InitHandlers(); + EXC_InitHandlers(); #endif return DD_OK; #else /* defined(HAVE_LIBXXF86DGA) */ @@ -3869,7 +3869,7 @@ static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) { #endif #ifdef RESTORE_SIGNALS - SIGNAL_InitHandlers(); + EXC_InitHandlers(); #endif HeapFree(GetProcessHeap(),0,This); return 0; @@ -4765,7 +4765,7 @@ HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) depth = DefaultDepthOfScreen(X11DRV_GetXScreen()); _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL); #ifdef RESTORE_SIGNALS - SIGNAL_InitHandlers(); + EXC_InitHandlers(); #endif return DD_OK; diff --git a/include/miscemu.h b/include/miscemu.h index e55eddd4e51..969ed40a285 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -185,7 +185,6 @@ extern void WINAPI XMS_Handler(CONTEXT*); extern BOOL SIGNAL_Init(void); extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags ); extern void SIGNAL_MaskAsyncEvents( BOOL flag ); -extern void SIGNAL_InitHandlers(void); /* misc/aspi.c */ extern void ASPI_DOS_HandleInt(CONTEXT *context); diff --git a/include/sig_context.h b/include/sig_context.h index cd454f8f642..783ea26a7f6 100644 --- a/include/sig_context.h +++ b/include/sig_context.h @@ -159,6 +159,7 @@ typedef struct _CONTEXT /* Note 1 */ #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__ @@ -280,4 +281,7 @@ typedef DWORD SIGCONTEXT; #define HANDLER_CONTEXT 0 #endif +/* memory/instr.c */ +extern BOOL INSTR_EmulateInstruction( SIGCONTEXT * ); + #endif /* __WINE_SIG_CONTEXT_H */ diff --git a/loader/signal.c b/loader/signal.c index 5e3e6f51838..a0999b42c02 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -34,44 +33,12 @@ #include "winsock.h" #include "global.h" #include "options.h" -#include "debugger.h" #include "miscemu.h" #include "dosexe.h" #include "thread.h" +#include "wine/exception.h" #include "debugtools.h" -void (*fnWINE_Debugger)(int,SIGCONTEXT*) = NULL; -void (*ctx_debug_call)(int sig,CONTEXT*ctx)=NULL; -BOOL (*fnINSTR_EmulateInstruction)(SIGCONTEXT*ctx)=NULL; - - -#ifdef __i386__ - -/* i386 specific faults */ -static const char * const SIGNAL_traps[] = -{ - "Division by zero exception", /* 0 */ - "Debug exception", /* 1 */ - "NMI interrupt", /* 2 */ - "Breakpoint exception", /* 3 */ - "Overflow exception", /* 4 */ - "Bound range exception", /* 5 */ - "Invalid opcode exception", /* 6 */ - "Device not available exception", /* 7 */ - "Double fault exception", /* 8 */ - "Coprocessor segment overrun", /* 9 */ - "Invalid TSS exception", /* 10 */ - "Segment not present exception", /* 11 */ - "Stack fault", /* 12 */ - "General protection fault", /* 13 */ - "Page fault", /* 14 */ - "Unknown exception", /* 15 */ - "Floating point exception", /* 16 */ - "Alignment check exception", /* 17 */ - "Machine check exception" /* 18 */ -}; -#define NB_TRAPS (sizeof(SIGNAL_traps) / sizeof(SIGNAL_traps[0])) -#endif /* Linux sigaction function */ @@ -199,114 +166,6 @@ void SIGNAL_MaskAsyncEvents( BOOL flag ) sigprocmask( (flag) ? SIG_BLOCK : SIG_UNBLOCK , &async_signal_set, NULL); } -extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags ); - -/********************************************************************** - * SIGNAL_break - * - * Handle Ctrl-C and such - */ -static HANDLER_DEF(SIGNAL_break) -{ - HANDLER_INIT(); - if (Options.debug && fnWINE_Debugger) - fnWINE_Debugger( signal, HANDLER_CONTEXT ); /* Enter our debugger */ - else exit(0); -} - - -/********************************************************************** - * SIGNAL_trap - * - * SIGTRAP handler. - */ -static HANDLER_DEF(SIGNAL_trap) -{ - HANDLER_INIT(); - if (fnWINE_Debugger) - fnWINE_Debugger( signal, HANDLER_CONTEXT ); /* Enter our debugger */ -} - - -/********************************************************************** - * SIGNAL_fault - * - * Segfault handler. - */ -static HANDLER_DEF(SIGNAL_fault) -{ - const char *fault = "Segmentation fault"; - HANDLER_INIT(); - -#ifdef __i386__ - -#if defined(TRAP_sig) && defined(CR2_sig) - if (TRAP_sig(HANDLER_CONTEXT) == 0x0e - && VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) - return; -#endif -#if defined(TRAP_sig) - /* We don't do alignment checks */ - /* FIXME: if we get SEHs, pass the fault through them first? */ - if (TRAP_sig(HANDLER_CONTEXT) == 0x11) { - if (EFL_sig(HANDLER_CONTEXT) & 0x00040000) { - /* Disable AC flag, return */ - EFL_sig(HANDLER_CONTEXT) &= ~0x00040000; - return; - } - } -#endif - - if (fnINSTR_EmulateInstruction && - fnINSTR_EmulateInstruction( HANDLER_CONTEXT ) - ) - return; - -#ifdef TRAP_sig - if (TRAP_sig( HANDLER_CONTEXT ) < NB_TRAPS) - fault = SIGNAL_traps[TRAP_sig( HANDLER_CONTEXT )]; -#endif - if (IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT))) - { - MESSAGE("%s in 32-bit code (0x%08lx).\n", fault, EIP_sig(HANDLER_CONTEXT)); - } - else - { - MESSAGE("%s in 16-bit code (%04x:%04lx).\n", fault, - (WORD)CS_sig(HANDLER_CONTEXT), EIP_sig(HANDLER_CONTEXT) ); - } -#ifdef CR2_sig - MESSAGE("Fault address is 0x%08lx\n",CR2_sig(HANDLER_CONTEXT)); -#endif -#endif - - if (fnWINE_Debugger) - fnWINE_Debugger( signal, HANDLER_CONTEXT ); - else { - MESSAGE("stopping pid %d due to unhandled %s.\n",getpid(),fault); - kill(getpid(),SIGSTOP); - } -} - - -/********************************************************************** - * SIGNAL_InitHandlers - */ -void SIGNAL_InitHandlers(void) -{ - SIGNAL_SetHandler( SIGINT, (void (*)())SIGNAL_break, 1); - SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault, 1); - SIGNAL_SetHandler( SIGILL, (void (*)())SIGNAL_fault, 1); - SIGNAL_SetHandler( SIGFPE, (void (*)())SIGNAL_fault, 1); -#ifdef SIGTRAP - SIGNAL_SetHandler( SIGTRAP, (void (*)())SIGNAL_trap, 1); /* debugger */ -#endif - SIGNAL_SetHandler( SIGHUP, (void (*)())SIGNAL_trap, 1); /* forced break*/ -#ifdef SIGBUS - SIGNAL_SetHandler( SIGBUS, (void (*)())SIGNAL_fault, 1); -#endif - return; -} /********************************************************************** * SIGNAL_Init @@ -341,6 +200,6 @@ BOOL SIGNAL_Init(void) /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead */ signal (SIGPIPE, SIG_IGN); - SIGNAL_InitHandlers(); + EXC_InitHandlers(); return TRUE; }