#ifdef LISP_FEATURE_X86
/* Suppose the existence of some function that saved all
* registers, called call_into_lisp, then restored GP registers and
- * returned. We shortcut this: fake the stack that call_into_lisp
- * would see, then arrange to have it called directly. post_signal_tramp
- * is the second half of this function
+ * returned. It would look something like this:
+
+ push ebp
+ mov ebp esp
+ pushad
+ push $0
+ push $0
+ pushl {address of function to call}
+ call 0x8058db0 <call_into_lisp>
+ addl $12,%esp
+ popa
+ leave
+ ret
+
+ * What we do here is set up the stack that call_into_lisp would
+ * expect to see if it had been called by this code, and frob the
+ * signal context so that signal return goes directly to call_into_lisp,
+ * and when that function (and the lisp function it invoked) returns,
+ * it returns to the second half of this imaginary function which
+ * restores all registers and returns to C
+
+ * For this to work, the latter part of the imaginary function
+ * must obviously exist in reality. That would be post_signal_tramp
*/
+
u32 *sp=(u32 *)*os_context_register_addr(context,reg_ESP);
*(sp-14) = post_signal_tramp; /* return address for call_into_lisp */
/* this order matches that used in POPAD */
*(sp-10)=*os_context_register_addr(context,reg_EDI);
*(sp-9)=*os_context_register_addr(context,reg_ESI);
- /* this gets overwritten again before it's used, anyway */
- *(sp-8)=*os_context_register_addr(context,reg_EBP);
- *(sp-7)=0 ; /* POPAD doesn't set ESP, but expects a gap for it anyway */
+
+ *(sp-8)=*os_context_register_addr(context,reg_ESP)-8;
+ *(sp-7)=0;
*(sp-6)=*os_context_register_addr(context,reg_EBX);
*(sp-5)=*os_context_register_addr(context,reg_EDX);
*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
#else
/* this much of the calling convention is common to all
non-x86 ports */
{ /* called when a child thread exits */
mark_dead_threads();
}
-
#endif
-boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr){
+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,
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_ERROR));
+ return 1;
+ }
else return 0;
}