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)
|
#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;
|
||||||
|
|
Loading…
Reference in New Issue