vm: clean up signal handling and add EXC_BAD_INSTRUCTION Mach exception handler for OS X, since signal handlers cannot change the stack pointer
parent
6c1a70c218
commit
f24942e063
|
@ -47,7 +47,7 @@ void factor_vm::call_fault_handler(
|
||||||
else
|
else
|
||||||
signal_callstack_top = NULL;
|
signal_callstack_top = NULL;
|
||||||
|
|
||||||
MACH_STACK_POINTER(thread_state) = fix_stack_pointer(MACH_STACK_POINTER(thread_state));
|
MACH_STACK_POINTER(thread_state) = align_stack_pointer(MACH_STACK_POINTER(thread_state));
|
||||||
|
|
||||||
/* Now we point the program counter at the right handler function. */
|
/* Now we point the program counter at the right handler function. */
|
||||||
if(exception == EXC_BAD_ACCESS)
|
if(exception == EXC_BAD_ACCESS)
|
||||||
|
@ -63,7 +63,13 @@ void factor_vm::call_fault_handler(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
signal_number = (exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT);
|
switch(exception)
|
||||||
|
{
|
||||||
|
case EXC_ARITHMETIC: signal_number = SIGFPE; break;
|
||||||
|
case EXC_BAD_INSTRUCTION: signal_number = SIGILL; break;
|
||||||
|
default: signal_number = SIGABRT; break;
|
||||||
|
}
|
||||||
|
|
||||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::misc_signal_handler_impl;
|
MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::misc_signal_handler_impl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +232,7 @@ void mach_initialize ()
|
||||||
fatal_error("mach_port_insert_right() failed",0);
|
fatal_error("mach_port_insert_right() failed",0);
|
||||||
|
|
||||||
/* The exceptions we want to catch. */
|
/* The exceptions we want to catch. */
|
||||||
mask = EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC;
|
mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC;
|
||||||
|
|
||||||
/* Create the thread listening on the exception port. */
|
/* Create the thread listening on the exception port. */
|
||||||
start_thread(mach_exception_thread,NULL);
|
start_thread(mach_exception_thread,NULL);
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.mc_esp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static unsigned int uap_fpu_status(void *uap)
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
{
|
{
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
@ -43,6 +37,8 @@ inline static void uap_clear_fpu_status(void *uap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_eip)
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_esp)
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_eip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.mc_rsp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static unsigned int uap_fpu_status(void *uap)
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
{
|
{
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
@ -33,6 +27,8 @@ inline static void uap_clear_fpu_status(void *uap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_rip)
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_rsp)
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_rip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,9 @@ void early_init();
|
||||||
const char *vm_executable_path();
|
const char *vm_executable_path();
|
||||||
const char *default_image_path();
|
const char *default_image_path();
|
||||||
|
|
||||||
|
inline static cell align_stack_pointer(cell sp)
|
||||||
|
{
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,9 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.arm_sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.arm_pc)
|
|
||||||
|
|
||||||
void flush_icache(cell start, cell len);
|
void flush_icache(cell start, cell len);
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_sp)
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_pc)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,7 @@ namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
#define FRAME_RETURN_ADDRESS(frame,vm) *((void **)(vm->frame_successor(frame) + 1) + 1)
|
#define FRAME_RETURN_ADDRESS(frame,vm) *((void **)(vm->frame_successor(frame) + 1) + 1)
|
||||||
|
#define UAP_STACK_POINTER(ucontext) ((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[PT_R1]
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[PT_NIP])
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.uc_regs->gregs[PT_R1];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.uc_regs->gregs[PT_NIP])
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,6 @@ struct _fpstate {
|
||||||
|
|
||||||
#define X86_FXSR_MAGIC 0x0000
|
#define X86_FXSR_MAGIC 0x0000
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.gregs[7];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static unsigned int uap_fpu_status(void *uap)
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
{
|
{
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
@ -54,7 +48,8 @@ inline static void uap_clear_fpu_status(void *uap)
|
||||||
fpregs->mxcsr &= 0xffffffc0;
|
fpregs->mxcsr &= 0xffffffc0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[14])
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[7])
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[14])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,6 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.gregs[15];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static unsigned int uap_fpu_status(void *uap)
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
{
|
{
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
@ -23,7 +17,7 @@ inline static void uap_clear_fpu_status(void *uap)
|
||||||
ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0;
|
ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[15])
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[16])
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[16])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ inline static unsigned int uap_fpu_status(void *uap)
|
||||||
return mach_fpu_status(UAP_FS(uap));
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell align_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ inline static unsigned int uap_fpu_status(void *uap)
|
||||||
return mach_fpu_status(UAP_FS(uap));
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell align_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return ((sp + 4) & ~15) - 4;
|
return ((sp + 4) & ~15) - 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ inline static unsigned int uap_fpu_status(void *uap)
|
||||||
return mach_fpu_status(UAP_FS(uap));
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell align_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return ((sp + 8) & ~15) - 8;
|
return ((sp + 8) & ~15) - 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,8 @@ void early_init();
|
||||||
const char *vm_executable_path();
|
const char *vm_executable_path();
|
||||||
const char *default_image_path();
|
const char *default_image_path();
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return ucontext->uc_stack.ss_sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_to_factor_toplevel(cell quot);
|
void c_to_factor_toplevel(cell quot);
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_stack.ss_sp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
|
|
||||||
|
|
||||||
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
static inline void uap_clear_fpu_status(void *uap) { }
|
static inline void uap_clear_fpu_status(void *uap) {}
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (_UC_MACHINE_SP((ucontext_t *)ucontext))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
#define ucontext_stack_pointer(uap) \
|
|
||||||
((void *)(((ucontext_t *)(uap))->uc_mcontext.__gregs[_REG_URSP]))
|
|
||||||
|
|
||||||
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
static inline void uap_clear_fpu_status(void *uap) { }
|
static inline void uap_clear_fpu_status(void *uap) {}
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.__gregs[_REG_URSP])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,10 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *openbsd_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
struct sigcontext *sc = (struct sigcontext*) uap;
|
|
||||||
return (void *)sc->sc_esp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ucontext_stack_pointer openbsd_stack_pointer
|
|
||||||
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_eip)
|
|
||||||
|
|
||||||
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
static inline void uap_clear_fpu_status(void *uap) { }
|
static inline void uap_clear_fpu_status(void *uap) {}
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((struct sigcontext *)ucontext)->sc_esp)
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((struct sigcontext *)ucontext)->sc_eip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,10 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *openbsd_stack_pointer(void *uap)
|
|
||||||
{
|
|
||||||
struct sigcontext *sc = (struct sigcontext*) uap;
|
|
||||||
return (void *)sc->sc_rsp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ucontext_stack_pointer openbsd_stack_pointer
|
|
||||||
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_rip)
|
|
||||||
|
|
||||||
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
static inline void uap_clear_fpu_status(void *uap) { }
|
static inline void uap_clear_fpu_status(void *uap) {}
|
||||||
|
|
||||||
|
#define UAP_STACK_POINTER(ucontext) (((struct sigcontext *)ucontext)->sc_rsp)
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) (((struct sigcontext *)ucontext)->sc_rip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,7 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[ESP])
|
||||||
{
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[EIP])
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.gregs[ESP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[EIP])
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,7 @@
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
|
||||||
inline static void *ucontext_stack_pointer(void *uap)
|
#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[RSP])
|
||||||
{
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[RIP])
|
||||||
ucontext_t *ucontext = (ucontext_t *)uap;
|
|
||||||
return (void *)ucontext->uc_mcontext.gregs[RSP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[RIP])
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,63 +115,47 @@ segment::~segment()
|
||||||
if(retval)
|
if(retval)
|
||||||
fatal_error("Segment deallocation failed",0);
|
fatal_error("Segment deallocation failed",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_frame *factor_vm::uap_stack_pointer(void *uap)
|
void factor_vm::dispatch_signal(void *uap, void (handler)())
|
||||||
{
|
{
|
||||||
/* There is a race condition here, but in practice a signal
|
|
||||||
delivered during stack frame setup/teardown or while transitioning
|
|
||||||
from Factor to C is a sign of things seriously gone wrong, not just
|
|
||||||
a divide by zero or stack underflow in the listener */
|
|
||||||
if(in_code_heap_p(UAP_PROGRAM_COUNTER(uap)))
|
if(in_code_heap_p(UAP_PROGRAM_COUNTER(uap)))
|
||||||
{
|
{
|
||||||
stack_frame *ptr = (stack_frame *)ucontext_stack_pointer(uap);
|
stack_frame *ptr = (stack_frame *)UAP_STACK_POINTER(uap);
|
||||||
if(!ptr)
|
assert(ptr);
|
||||||
critical_error("Invalid uap",(cell)uap);
|
signal_callstack_top = ptr;
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
signal_callstack_top = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
void factor_vm::memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
UAP_STACK_POINTER(uap) = (void *)align_stack_pointer((cell)UAP_STACK_POINTER(uap));
|
||||||
{
|
UAP_PROGRAM_COUNTER(uap) = (cell)handler;
|
||||||
signal_fault_addr = (cell)siginfo->si_addr;
|
|
||||||
signal_callstack_top = uap_stack_pointer(uap);
|
|
||||||
UAP_PROGRAM_COUNTER(uap) = (cell)factor::memory_signal_handler_impl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||||
{
|
{
|
||||||
tls_vm()->memory_signal_handler(signal,siginfo,uap);
|
factor_vm *vm = tls_vm();
|
||||||
}
|
vm->signal_fault_addr = (cell)siginfo->si_addr;
|
||||||
|
vm->dispatch_signal(uap,factor::memory_signal_handler_impl);
|
||||||
void factor_vm::misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
|
||||||
{
|
|
||||||
signal_number = signal;
|
|
||||||
signal_callstack_top = uap_stack_pointer(uap);
|
|
||||||
UAP_PROGRAM_COUNTER(uap) = (cell)factor::misc_signal_handler_impl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||||
{
|
{
|
||||||
tls_vm()->misc_signal_handler(signal,siginfo,uap);
|
factor_vm *vm = tls_vm();
|
||||||
}
|
vm->signal_number = signal;
|
||||||
|
vm->dispatch_signal(uap,factor::misc_signal_handler_impl);
|
||||||
void factor_vm::fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
|
||||||
{
|
|
||||||
signal_number = signal;
|
|
||||||
signal_callstack_top = uap_stack_pointer(uap);
|
|
||||||
signal_fpu_status = fpu_status(uap_fpu_status(uap));
|
|
||||||
uap_clear_fpu_status(uap);
|
|
||||||
UAP_PROGRAM_COUNTER(uap) =
|
|
||||||
(siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
|
|
||||||
? (cell)factor::misc_signal_handler_impl
|
|
||||||
: (cell)factor::fp_signal_handler_impl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||||
{
|
{
|
||||||
tls_vm()->fpe_signal_handler(signal, siginfo, uap);
|
factor_vm *vm = tls_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::misc_signal_handler_impl
|
||||||
|
: factor::fp_signal_handler_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
|
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||||
|
|
11
vm/vm.hpp
11
vm/vm.hpp
|
@ -689,17 +689,12 @@ struct factor_vm
|
||||||
void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);
|
void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);
|
||||||
bool windows_stat(vm_char *path);
|
bool windows_stat(vm_char *path);
|
||||||
|
|
||||||
#if defined(WINNT)
|
#if defined(WINNT)
|
||||||
void open_console();
|
void open_console();
|
||||||
LONG exception_handler(PEXCEPTION_POINTERS pe);
|
LONG exception_handler(PEXCEPTION_POINTERS pe);
|
||||||
// next method here:
|
#endif
|
||||||
#endif
|
|
||||||
#else // UNIX
|
#else // UNIX
|
||||||
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap);
|
void factor_vm::dispatch_signal(void *uap, void (handler)());
|
||||||
void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap);
|
|
||||||
void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap);
|
|
||||||
stack_frame *uap_stack_pointer(void *uap);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
Loading…
Reference in New Issue