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)
/* 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))
@ -254,7 +255,33 @@ typedef struct
#endif
#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
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
#endif /* TRAP_sig */
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;
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;