void factor_vm::dispatch_signal(void *uap, void (handler)()) { UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)fix_callstack_top((stack_frame *)UAP_STACK_POINTER(uap)); UAP_PROGRAM_COUNTER(uap) = (cell)handler; ctx->callstack_top = (stack_frame *)UAP_STACK_POINTER(uap); }
void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) { factor_vm* vm = current_vm(); vm->verify_memory_protection_error((cell)siginfo->si_addr); vm->signal_fault_addr = (cell)siginfo->si_addr; vm->signal_fault_pc = (cell)UAP_PROGRAM_COUNTER(uap); vm->dispatch_signal(uap, factor::memory_signal_handler_impl); }
void sample_signal_handler(int signal, siginfo_t* siginfo, void* uap) { factor_vm* vm = current_vm_p(); bool foreign_thread = false; if (vm == NULL) { foreign_thread = true; vm = thread_vms.begin()->second; } if (atomic::load(&vm->sampling_profiler_p)) vm->safepoint.enqueue_samples(vm, 1, (cell)UAP_PROGRAM_COUNTER(uap), foreign_thread); else if (!foreign_thread) enqueue_signal(vm, signal); }
INLINE F_STACK_FRAME *uap_stack_pointer(void *uap) { /* 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))) { F_STACK_FRAME *ptr = ucontext_stack_pointer(uap); if(!ptr) critical_error("Invalid uap",(CELL)uap); return ptr; } else return NULL; }
void 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)misc_signal_handler_impl; }
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap) { signal_fault_addr = (CELL)siginfo->si_addr; signal_callstack_top = uap_stack_pointer(uap); UAP_PROGRAM_COUNTER(uap) = (CELL)memory_signal_handler_impl; }
void factor_vm::dispatch_signal(void* uap, void(handler)()) { dispatch_signal_handler((cell*)&UAP_STACK_POINTER(uap), (cell*)&UAP_PROGRAM_COUNTER(uap), (cell)FUNCTION_CODE_POINTER(handler)); UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler)); }