Support TRAP_sig for FreeBSD (with the help of Juergen Lock).

This commit is contained in:
Alexandre Julliard 1999-09-28 13:15:27 +00:00
parent 20f7ef7355
commit de5e1af2bd
1 changed files with 79 additions and 42 deletions

View File

@ -212,6 +212,7 @@ typedef struct
#define EFL_sig(context) ((context)->sc_efl) #define EFL_sig(context) ((context)->sc_efl)
/* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge */ /* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge */
#define CR2_sig(context) ((context)->sc_err) #define CR2_sig(context) ((context)->sc_err)
#define TRAP_sig(context) ((context)->sc_trapno)
#endif #endif
#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip)) #define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
@ -254,7 +255,33 @@ typedef struct
#endif #endif
#endif /* svr4 || SCO_DS */ #endif /* svr4 || SCO_DS */
/* exception code definitions (already defined by FreeBSD) */
#ifndef __FreeBSD__ /* FIXME: other BSDs? */
#define T_DIVIDE 0 /* Division by zero exception */
#define T_TRCTRAP 1 /* Single-step exception */
#define T_NMI 2 /* NMI interrupt */
#define T_BPTFLT 3 /* Breakpoint exception */
#define T_OFLOW 4 /* Overflow exception */
#define T_BOUND 5 /* Bound range exception */
#define T_PRIVINFLT 6 /* Invalid opcode exception */
#define T_DNA 7 /* Device not available exception */
#define T_DOUBLEFLT 8 /* Double fault exception */
#define T_FPOPFLT 9 /* Coprocessor segment overrun */
#define T_TSSFLT 10 /* Invalid TSS exception */
#define T_SEGNPFLT 11 /* Segment not present exception */
#define T_STKFLT 12 /* Stack fault */
#define T_PROTFLT 13 /* General protection fault */
#define T_PAGEFLT 14 /* Page fault */
#define T_RESERVED 15 /* Unknown exception */
#define T_ARITHTRAP 16 /* Floating point exception */
#define T_ALIGNFLT 17 /* Alignment check exception */
#define T_MCHK 18 /* Machine check exception */
#define T_CACHEFLT 19 /* Cache flush exception */
#endif
#define T_UNKNOWN (-1) /* Unknown fault (TRAP_sig not defined) */
extern void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *context ); extern void WINAPI REGS_FUNC(RtlRaiseException)( EXCEPTION_RECORD *rec, CONTEXT *context );
@ -281,6 +308,19 @@ static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext
SET_FS(fs); SET_FS(fs);
} }
/***********************************************************************
* get_trap_code
*
* Get the trap code for a signal.
*/
static inline int get_trap_code( const SIGCONTEXT *sigcontext )
{
#ifdef TRAP_sig
return TRAP_sig(sigcontext);
#else
return T_UNKNOWN; /* unknown trap code */
#endif
}
/*********************************************************************** /***********************************************************************
* save_context * save_context
@ -427,9 +467,9 @@ static HANDLER_DEF(segv_handler)
handler_init( &context, HANDLER_CONTEXT ); handler_init( &context, HANDLER_CONTEXT );
#if defined(TRAP_sig) && defined(CR2_sig) #ifdef CR2_sig
/* we want the page-fault case to be fast */ /* we want the page-fault case to be fast */
if (TRAP_sig(HANDLER_CONTEXT) == 14) if (get_trap_code(HANDLER_CONTEXT) == T_PAGEFLT)
if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return; if (VIRTUAL_HandleFault( (LPVOID)CR2_sig(HANDLER_CONTEXT) )) return;
#endif #endif
@ -439,27 +479,27 @@ static HANDLER_DEF(segv_handler)
rec.ExceptionAddress = (LPVOID)context.Eip; rec.ExceptionAddress = (LPVOID)context.Eip;
rec.NumberParameters = 0; rec.NumberParameters = 0;
#ifdef TRAP_sig switch(get_trap_code(HANDLER_CONTEXT))
switch(TRAP_sig(HANDLER_CONTEXT))
{ {
case 4: /* Overflow exception */ case T_OFLOW: /* Overflow exception */
rec.ExceptionCode = EXCEPTION_INT_OVERFLOW; rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
break; break;
case 5: /* Bound range exception */ case T_BOUND: /* Bound range exception */
rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
break; break;
case 6: /* Invalid opcode exception */ case T_PRIVINFLT: /* Invalid opcode exception */
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
case 12: /* Stack fault */ case T_STKFLT: /* Stack fault */
rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW; rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
break; break;
case 11: /* Segment not present exception */ case T_SEGNPFLT: /* Segment not present exception */
case 13: /* General protection fault */ case T_PROTFLT: /* General protection fault */
case T_UNKNOWN: /* Unknown fault code */
if (INSTR_EmulateInstruction( &context )) goto restore; if (INSTR_EmulateInstruction( &context )) goto restore;
rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION; rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
break; break;
case 14: /* Page fault */ case T_PAGEFLT: /* Page fault */
#ifdef CR2_sig #ifdef CR2_sig
rec.NumberParameters = 2; rec.NumberParameters = 2;
#ifdef ERROR_sig #ifdef ERROR_sig
@ -471,7 +511,7 @@ static HANDLER_DEF(segv_handler)
#endif /* CR2_sig */ #endif /* CR2_sig */
rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION; rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
break; break;
case 17: /* Alignment check exception */ case T_ALIGNFLT: /* Alignment check exception */
/* FIXME: pass through exception handler first? */ /* FIXME: pass through exception handler first? */
if (context.EFlags & 0x00040000) if (context.EFlags & 0x00040000)
{ {
@ -482,22 +522,20 @@ static HANDLER_DEF(segv_handler)
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 %d\n", get_trap_code(HANDLER_CONTEXT) );
/* fall through */ /* fall through */
case 2: /* NMI interrupt */ case T_NMI: /* NMI interrupt */
case 7: /* Device not available exception */ case T_DNA: /* Device not available exception */
case 8: /* Double fault exception */ case T_DOUBLEFLT: /* Double fault exception */
case 10: /* Invalid TSS exception */ case T_TSSFLT: /* Invalid TSS exception */
case 15: /* Unknown exception */ case T_RESERVED: /* Unknown exception */
case 18: /* Machine check exception */ case T_MCHK: /* Machine check exception */
case 19: /* Cache flush exception */ #ifdef T_CACHEFLT
case T_CACHEFLT: /* Cache flush exception */
#endif
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
} }
#else /* TRAP_sig */
if (INSTR_EmulateInstruction( &context )) return;
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; /* generic error */
#endif /* TRAP_sig */
REGS_FUNC(RtlRaiseException)( &rec, &context ); REGS_FUNC(RtlRaiseException)( &rec, &context );
restore: restore:
@ -517,13 +555,16 @@ static HANDLER_DEF(trap_handler)
handler_init( &context, HANDLER_CONTEXT ); handler_init( &context, HANDLER_CONTEXT );
#ifdef TRAP_sig switch(get_trap_code(HANDLER_CONTEXT))
rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ? {
EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT; case T_TRCTRAP: /* Single-step exception */
#else rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
rec.ExceptionCode = EXCEPTION_BREAKPOINT; break;
#endif /* TRAP_sig */ case T_BPTFLT: /* Breakpoint exception */
default:
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
break;
}
save_context( &context, HANDLER_CONTEXT ); save_context( &context, HANDLER_CONTEXT );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;
@ -548,27 +589,23 @@ static HANDLER_DEF(fpe_handler)
save_fpu( &context, HANDLER_CONTEXT ); save_fpu( &context, HANDLER_CONTEXT );
#ifdef TRAP_sig switch(get_trap_code(HANDLER_CONTEXT))
switch(TRAP_sig(HANDLER_CONTEXT))
{ {
case 0: /* Division by zero exception */ case T_DIVIDE: /* Division by zero exception */
rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
break; break;
case 9: /* Coprocessor segment overrun */ case T_FPOPFLT: /* Coprocessor segment overrun */
rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break; break;
case 16: /* Floating point exception */ case T_ARITHTRAP: /* Floating point exception */
case T_UNKNOWN: /* Unknown fault code */
rec.ExceptionCode = get_fpu_code( &context ); rec.ExceptionCode = get_fpu_code( &context );
break; break;
default: default:
ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) ); ERR( "Got unexpected trap %d\n", get_trap_code(HANDLER_CONTEXT) );
rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break; break;
} }
#else /* TRAP_sig */
rec.ExceptionCode = get_fpu_code( &context );
#endif /* TRAP_sig */
save_context( &context, HANDLER_CONTEXT ); save_context( &context, HANDLER_CONTEXT );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE; rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL; rec.ExceptionRecord = NULL;