Support TRAP_sig for FreeBSD (with the help of Juergen Lock).
This commit is contained in:
parent
20f7ef7355
commit
de5e1af2bd
|
@ -212,6 +212,7 @@ typedef struct
|
|||
#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)
|
||||
#define TRAP_sig(context) ((context)->sc_trapno)
|
||||
#endif
|
||||
|
||||
#define EIP_sig(context) (*((unsigned long*)&(context)->sc_eip))
|
||||
|
@ -256,6 +257,32 @@ typedef struct
|
|||
#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 );
|
||||
|
||||
|
||||
|
@ -281,6 +308,19 @@ static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext
|
|||
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
|
||||
|
@ -427,9 +467,9 @@ static HANDLER_DEF(segv_handler)
|
|||
|
||||
handler_init( &context, HANDLER_CONTEXT );
|
||||
|
||||
#if defined(TRAP_sig) && defined(CR2_sig)
|
||||
#ifdef CR2_sig
|
||||
/* 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;
|
||||
#endif
|
||||
|
||||
|
@ -439,27 +479,27 @@ static HANDLER_DEF(segv_handler)
|
|||
rec.ExceptionAddress = (LPVOID)context.Eip;
|
||||
rec.NumberParameters = 0;
|
||||
|
||||
#ifdef TRAP_sig
|
||||
switch(TRAP_sig(HANDLER_CONTEXT))
|
||||
switch(get_trap_code(HANDLER_CONTEXT))
|
||||
{
|
||||
case 4: /* Overflow exception */
|
||||
case T_OFLOW: /* Overflow exception */
|
||||
rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
|
||||
break;
|
||||
case 5: /* Bound range exception */
|
||||
case T_BOUND: /* Bound range exception */
|
||||
rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
|
||||
break;
|
||||
case 6: /* Invalid opcode exception */
|
||||
case T_PRIVINFLT: /* Invalid opcode exception */
|
||||
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
|
||||
break;
|
||||
case 12: /* Stack fault */
|
||||
case T_STKFLT: /* Stack fault */
|
||||
rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
|
||||
break;
|
||||
case 11: /* Segment not present exception */
|
||||
case 13: /* General protection fault */
|
||||
case T_SEGNPFLT: /* Segment not present exception */
|
||||
case T_PROTFLT: /* General protection fault */
|
||||
case T_UNKNOWN: /* Unknown fault code */
|
||||
if (INSTR_EmulateInstruction( &context )) goto restore;
|
||||
rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
|
||||
break;
|
||||
case 14: /* Page fault */
|
||||
case T_PAGEFLT: /* Page fault */
|
||||
#ifdef CR2_sig
|
||||
rec.NumberParameters = 2;
|
||||
#ifdef ERROR_sig
|
||||
|
@ -471,7 +511,7 @@ static HANDLER_DEF(segv_handler)
|
|||
#endif /* CR2_sig */
|
||||
rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
|
||||
break;
|
||||
case 17: /* Alignment check exception */
|
||||
case T_ALIGNFLT: /* Alignment check exception */
|
||||
/* FIXME: pass through exception handler first? */
|
||||
if (context.EFlags & 0x00040000)
|
||||
{
|
||||
|
@ -482,22 +522,20 @@ static HANDLER_DEF(segv_handler)
|
|||
rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
|
||||
break;
|
||||
default:
|
||||
ERR( "Got unexpected trap %ld\n", TRAP_sig(HANDLER_CONTEXT) );
|
||||
ERR( "Got unexpected trap %d\n", get_trap_code(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 */
|
||||
case T_NMI: /* NMI interrupt */
|
||||
case T_DNA: /* Device not available exception */
|
||||
case T_DOUBLEFLT: /* Double fault exception */
|
||||
case T_TSSFLT: /* Invalid TSS exception */
|
||||
case T_RESERVED: /* Unknown exception */
|
||||
case T_MCHK: /* Machine check exception */
|
||||
#ifdef T_CACHEFLT
|
||||
case T_CACHEFLT: /* Cache flush exception */
|
||||
#endif
|
||||
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:
|
||||
|
@ -517,13 +555,16 @@ static HANDLER_DEF(trap_handler)
|
|||
|
||||
handler_init( &context, HANDLER_CONTEXT );
|
||||
|
||||
#ifdef TRAP_sig
|
||||
rec.ExceptionCode = (TRAP_sig(HANDLER_CONTEXT) == 1) ?
|
||||
EXCEPTION_SINGLE_STEP : EXCEPTION_BREAKPOINT;
|
||||
#else
|
||||
switch(get_trap_code(HANDLER_CONTEXT))
|
||||
{
|
||||
case T_TRCTRAP: /* Single-step exception */
|
||||
rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
|
||||
break;
|
||||
case T_BPTFLT: /* Breakpoint exception */
|
||||
default:
|
||||
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
|
||||
#endif /* TRAP_sig */
|
||||
|
||||
break;
|
||||
}
|
||||
save_context( &context, HANDLER_CONTEXT );
|
||||
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
|
||||
rec.ExceptionRecord = NULL;
|
||||
|
@ -548,27 +589,23 @@ static HANDLER_DEF(fpe_handler)
|
|||
|
||||
save_fpu( &context, HANDLER_CONTEXT );
|
||||
|
||||
#ifdef TRAP_sig
|
||||
switch(TRAP_sig(HANDLER_CONTEXT))
|
||||
switch(get_trap_code(HANDLER_CONTEXT))
|
||||
{
|
||||
case 0: /* Division by zero exception */
|
||||
case T_DIVIDE: /* Division by zero exception */
|
||||
rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
|
||||
break;
|
||||
case 9: /* Coprocessor segment overrun */
|
||||
case T_FPOPFLT: /* Coprocessor segment overrun */
|
||||
rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
|
||||
break;
|
||||
case 16: /* Floating point exception */
|
||||
case T_ARITHTRAP: /* Floating point exception */
|
||||
case T_UNKNOWN: /* Unknown fault code */
|
||||
rec.ExceptionCode = get_fpu_code( &context );
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue