X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fruntime%2Finterrupt.c;h=65f50bf41ab6f4aec771c2eba4ff62d811a90124;hb=fd00d78accb69be3a626a29120ba17a18569b98c;hp=6bd4351305a1f19b8b47f3e0da3bbeed6d986e45;hpb=83312cce6ee1c74fe99805831afb5cfbcb4248bd;p=sbcl.git diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 6bd4351..65f50bf 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -161,7 +161,7 @@ void reset_signal_mask () void build_fake_control_stack_frames(struct thread *th,os_context_t *context) { -#ifndef LISP_FEATURE_X86 +#ifndef LISP_FEATURE_C_STACK_IS_CONTROL_STACK lispobj oldcont; @@ -364,7 +364,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) { os_context_t *context = (os_context_t*)void_context; struct thread *thread=arch_os_get_current_thread(); -#ifndef LISP_FEATURE_X86 +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) boolean were_in_lisp; #endif union interrupt_handler handler; @@ -381,7 +381,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) return; } -#ifndef LISP_FEATURE_X86 +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) were_in_lisp = !foreign_function_call_active; if (were_in_lisp) #endif @@ -440,7 +440,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) (*handler.c)(signal, info, void_context); } -#ifndef LISP_FEATURE_X86 +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) if (were_in_lisp) #endif { @@ -481,7 +481,7 @@ maybe_defer_handler(void *handler, struct interrupt_data *data, * actually use its argument for anything on x86, so this branch * may succeed even when context is null (gencgc alloc()) */ if ( -#ifndef LISP_FEATURE_X86 +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) (!foreign_function_call_active) && #endif arch_pseudo_atomic_atomic(context)) { @@ -670,6 +670,32 @@ void arrange_return_to_lisp_function(os_context_t *context, lispobj function) *(sp-2)=*os_context_register_addr(context,reg_EBP); *(sp-1)=*os_context_pc_addr(context); +#elif defined(LISP_FEATURE_X86_64) + u64 *sp=(u64 *)*os_context_register_addr(context,reg_RSP); + *(sp-19) = post_signal_tramp; /* return address for call_into_lisp */ + + *(sp-18)=*os_context_register_addr(context,reg_R15); + *(sp-17)=*os_context_register_addr(context,reg_R14); + *(sp-16)=*os_context_register_addr(context,reg_R13); + *(sp-15)=*os_context_register_addr(context,reg_R12); + *(sp-14)=*os_context_register_addr(context,reg_R11); + *(sp-13)=*os_context_register_addr(context,reg_R10); + *(sp-12)=*os_context_register_addr(context,reg_R9); + *(sp-11)=*os_context_register_addr(context,reg_R8); + *(sp-10)=*os_context_register_addr(context,reg_RDI); + *(sp-9)=*os_context_register_addr(context,reg_RSI); + *(sp-8)=*os_context_register_addr(context,reg_RSP)-16; + *(sp-7)=0; + *(sp-6)=*os_context_register_addr(context,reg_RBX); + *(sp-5)=*os_context_register_addr(context,reg_RDX); + *(sp-4)=*os_context_register_addr(context,reg_RCX); + *(sp-3)=*os_context_register_addr(context,reg_RAX); + *(sp-2)=*os_context_register_addr(context,reg_RBP); + *(sp-1)=*os_context_pc_addr(context); + + *os_context_register_addr(context,reg_RDI) = function; /* function */ + *os_context_register_addr(context,reg_RSI) = 0; /* arg. array */ + *os_context_register_addr(context,reg_RDX) = 0; /* no. args */ #else struct thread *th=arch_os_get_current_thread(); build_fake_control_stack_frames(th,context); @@ -679,7 +705,16 @@ void arrange_return_to_lisp_function(os_context_t *context, lispobj function) *os_context_pc_addr(context) = call_into_lisp; *os_context_register_addr(context,reg_ECX) = 0; *os_context_register_addr(context,reg_EBP) = sp-2; +#ifdef __NetBSD__ + *os_context_register_addr(context,reg_UESP) = sp-14; +#else *os_context_register_addr(context,reg_ESP) = sp-14; +#endif +#elif defined(LISP_FEATURE_X86_64) + *os_context_pc_addr(context) = call_into_lisp; + *os_context_register_addr(context,reg_RCX) = 0; + *os_context_register_addr(context,reg_RBP) = sp-2; + *os_context_register_addr(context,reg_RSP) = sp-19; #else /* this much of the calling convention is common to all non-x86 ports */ @@ -716,11 +751,20 @@ void thread_exit_handler(int num, siginfo_t *info, void *v_context) { /* called when a child thread exits */ mark_dead_threads(); } - #endif -boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr){ +/* KLUDGE: Theoretically the approach we use for undefined alien + * variables should work for functions as well, but on PPC/Darwin + * we get bus error at bogus addresses instead, hence this workaround, + * that has the added benefit of automatically discriminating between + * functions and variables. + */ +void undefined_alien_function() { + funcall0(SymbolFunction(UNDEFINED_ALIEN_FUNCTION_ERROR)); +} + +boolean handle_guard_page_triggered(os_context_t *context,void *addr){ struct thread *th=arch_os_get_current_thread(); /* note the os_context hackery here. When the signal handler returns, @@ -748,6 +792,12 @@ boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr){ protect_control_stack_return_guard_page(th->pid,0); return 1; } + else if (addr >= undefined_alien_address && + addr < undefined_alien_address + os_vm_page_size) { + arrange_return_to_lisp_function + (context, SymbolFunction(UNDEFINED_ALIEN_VARIABLE_ERROR)); + return 1; + } else return 0; }