diff --git a/vm/callstack.cpp b/vm/callstack.cpp index a0bbae8709..134a7c78b2 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -18,22 +18,6 @@ callstack *factor_vm::allot_callstack(cell size) return stack; } -/* If 'stack' points into the middle of the frame, find the nearest valid stack -pointer where we can resume execution and hope to capture the call trace without -crashing. Also, make sure we have at least 'stack_reserved' bytes available so -that we don't run out of callstack space while handling the error. */ -stack_frame *factor_vm::fix_callstack_top(stack_frame *stack) -{ - stack_frame *frame = ctx->callstack_bottom - 1; - - while(frame >= stack - && frame >= ctx->callstack_top - && (cell)frame >= ctx->callstack_seg->start + stack_reserved) - frame = frame_successor(frame); - - return frame + 1; -} - /* We ignore the two topmost frames, the 'callstack' primitive frame itself, and the frame calling the 'callstack' primitive, so that set-callstack doesn't get stuck in an infinite loop. @@ -127,13 +111,6 @@ void factor_vm::set_frame_offset(stack_frame *frame, cell offset) FRAME_RETURN_ADDRESS(frame,this) = entry_point + offset; } -void factor_vm::scrub_return_address() -{ - stack_frame *frame = innermost_stack_frame(ctx->callstack_bottom, - ctx->callstack_top); - set_frame_offset(frame,0); -} - cell factor_vm::frame_scan(stack_frame *frame) { switch(frame_type(frame)) diff --git a/vm/errors.cpp b/vm/errors.cpp index f0df0acbb8..23924df4e5 100755 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -125,7 +125,6 @@ void factor_vm::primitive_unimplemented() void factor_vm::memory_signal_handler_impl() { - scrub_return_address(); memory_protection_error(signal_fault_addr); } @@ -136,7 +135,6 @@ void memory_signal_handler_impl() void factor_vm::synchronous_signal_handler_impl() { - scrub_return_address(); signal_error(signal_number); } @@ -150,7 +148,6 @@ void factor_vm::fp_signal_handler_impl() /* Clear pending exceptions to avoid getting stuck in a loop */ set_fpu_state(get_fpu_state()); - scrub_return_address(); fp_trap_error(signal_fpu_status); } diff --git a/vm/mach_signal.cpp b/vm/mach_signal.cpp index 469b9f2ef6..1ad07791cc 100755 --- a/vm/mach_signal.cpp +++ b/vm/mach_signal.cpp @@ -35,7 +35,11 @@ void factor_vm::call_fault_handler( MACH_THREAD_STATE_TYPE *thread_state, MACH_FLOAT_STATE_TYPE *float_state) { - MACH_STACK_POINTER(thread_state) = (cell)fix_callstack_top((stack_frame *)MACH_STACK_POINTER(thread_state)); + cell offset = MACH_STACK_POINTER(thread_state) % 16; + if (offset != 0) + fatal_error("fault in unaligned frame with offset", offset); + MACH_STACK_POINTER(thread_state) -= sizeof(cell); + *(cell*)MACH_STACK_POINTER(thread_state) = MACH_PROGRAM_COUNTER(thread_state); ctx->callstack_top = (stack_frame *)MACH_STACK_POINTER(thread_state); diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index a198f10a1e..efd3e03bb2 100755 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -138,7 +138,12 @@ void code_heap::unguard_safepoint() 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)); + cell sp = (cell)UAP_STACK_POINTER(uap); + cell offset = sp % 16; + if (offset != 0) + fatal_error("fault in unaligned frame with offset", offset); + UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)(sp - sizeof(cell)); + *(cell*)(UAP_STACK_POINTER(uap)) = (cell)UAP_PROGRAM_COUNTER(uap); UAP_PROGRAM_COUNTER(uap) = (cell)FUNCTION_CODE_POINTER(handler); UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler)); ctx->callstack_top = (stack_frame *)UAP_STACK_POINTER(uap);