Exemplo n.º 1
0
int fpu_post_test (int flags)
{
	int fpu = fpu_status ();

	int ret = 0;

	WATCHDOG_RESET ();

	if (!fpu)
		fpu_enable ();

	if (ret == 0)
		ret = fpu_post_test_math1 ();
	if (ret == 0)
		ret = fpu_post_test_math2 ();
	if (ret == 0)
		ret = fpu_post_test_math3 ();
	if (ret == 0)
		ret = fpu_post_test_math4 ();
	if (ret == 0)
		ret = fpu_post_test_math5 ();
	if (ret == 0)
		ret = fpu_post_test_math6 ();
	if (ret == 0)
		ret = fpu_post_test_math7 ();

	if (!fpu)
		fpu_disable ();

	WATCHDOG_RESET ();

	return ret;
}
Exemplo n.º 2
0
void fpe_signal_handler(int signal, siginfo_t* siginfo, void* uap) {
  factor_vm* vm = current_vm();
  vm->signal_number = signal;
  vm->signal_fpu_status = fpu_status(uap_fpu_status(uap));
  uap_clear_fpu_status(uap);

  vm->dispatch_signal(
      uap, (siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
               ? factor::synchronous_signal_handler_impl
               : factor::fp_signal_handler_impl);
}
Exemplo n.º 3
0
LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c,
                                  void* dispatch) {
  switch (e->ExceptionCode) {
    case EXCEPTION_ACCESS_VIOLATION:
      signal_fault_addr = e->ExceptionInformation[1];
      signal_fault_pc = c->EIP;
      verify_memory_protection_error(signal_fault_addr);
      dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP,
                              (cell)factor::memory_signal_handler_impl);
      break;

    case STATUS_FLOAT_DENORMAL_OPERAND:
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
    case STATUS_FLOAT_INEXACT_RESULT:
    case STATUS_FLOAT_INVALID_OPERATION:
    case STATUS_FLOAT_OVERFLOW:
    case STATUS_FLOAT_STACK_CHECK:
    case STATUS_FLOAT_UNDERFLOW:
    case STATUS_FLOAT_MULTIPLE_FAULTS:
    case STATUS_FLOAT_MULTIPLE_TRAPS:
#ifdef FACTOR_64
      signal_fpu_status = fpu_status(MXCSR(c));
#else
      signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));

      // This seems to have no effect
      X87SW(c) = 0;
#endif
      MXCSR(c) &= 0xffffffc0;
      dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP,
                              (cell)factor::fp_signal_handler_impl);
      break;
    default:
      signal_number = e->ExceptionCode;
      dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP,
                              (cell)factor::synchronous_signal_handler_impl);
      break;
  }
  return ExceptionContinueExecution;
}
Exemplo n.º 4
0
LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
{
	c->ESP = (cell)fix_callstack_top((stack_frame *)c->ESP);
	ctx->callstack_top = (stack_frame *)c->ESP;

	switch (e->ExceptionCode)
	{
	case EXCEPTION_ACCESS_VIOLATION:
		signal_fault_addr = e->ExceptionInformation[1];
		c->EIP = (cell)factor::memory_signal_handler_impl;
		break;

	case STATUS_FLOAT_DENORMAL_OPERAND:
	case STATUS_FLOAT_DIVIDE_BY_ZERO:
	case STATUS_FLOAT_INEXACT_RESULT:
	case STATUS_FLOAT_INVALID_OPERATION:
	case STATUS_FLOAT_OVERFLOW:
	case STATUS_FLOAT_STACK_CHECK:
	case STATUS_FLOAT_UNDERFLOW:
	case STATUS_FLOAT_MULTIPLE_FAULTS:
	case STATUS_FLOAT_MULTIPLE_TRAPS:
#ifdef FACTOR_64
		signal_fpu_status = fpu_status(MXCSR(c));
#else
		signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));

		/* This seems to have no effect */
		X87SW(c) = 0;
#endif
		MXCSR(c) &= 0xffffffc0;
		c->EIP = (cell)factor::fp_signal_handler_impl;
		break;
	default:
		signal_number = e->ExceptionCode;
		c->EIP = (cell)factor::misc_signal_handler_impl;
		break;
	}

	return 0;
}
Exemplo n.º 5
0
/* Modify a suspended thread's thread_state so that when the thread resumes
   executing, the call frame of the current C primitive (if any) is rewound, and
   the appropriate Factor error is thrown from the top-most Factor frame. */
void factor_vm::call_fault_handler(exception_type_t exception,
                                   exception_data_type_t code,
                                   MACH_EXC_STATE_TYPE* exc_state,
                                   MACH_THREAD_STATE_TYPE* thread_state,
                                   MACH_FLOAT_STATE_TYPE* float_state) {
  cell handler = 0;

  if (exception == EXC_BAD_ACCESS) {
    signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
    signal_fault_pc = (cell)MACH_PROGRAM_COUNTER(thread_state);
    verify_memory_protection_error(signal_fault_addr);
    handler = (cell)factor::memory_signal_handler_impl;
  } else if (exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV) {
    signal_fpu_status = fpu_status(mach_fpu_status(float_state));
    mach_clear_fpu_status(float_state);
    handler = (cell)factor::fp_signal_handler_impl;
  } else {
    switch (exception) {
      case EXC_ARITHMETIC:
        signal_number = SIGFPE;
        break;
      case EXC_BAD_INSTRUCTION:
        signal_number = SIGILL;
        break;
      default:
        signal_number = SIGABRT;
        break;
    }

    handler = (cell)factor::synchronous_signal_handler_impl;
  }

  FACTOR_ASSERT(handler != 0);

  dispatch_signal_handler((cell*)&MACH_STACK_POINTER(thread_state),
                          (cell*)&MACH_PROGRAM_COUNTER(thread_state),
                          (cell)handler);
}