#include "sbcl.h"
#include "validate.h"
#include "genesis/closure.h"
+#include "genesis/funcallable-instance.h"
#include "genesis/fdefn.h"
#include "genesis/static-symbols.h"
#include "genesis/symbol.h"
Ldone:
/* Registers eax, ecx, edx, edi, and esi are now live. */
+#ifdef LISP_FEATURE_WIN32
+ /* Establish an SEH frame. */
+#ifdef LISP_FEATURE_SB_THREAD
+ /* FIXME: need to save BSP here. */
+#error "need to save BSP here, but don't know how yet."
+#else
+ pushl BINDING_STACK_POINTER + SYMBOL_VALUE_OFFSET
+#endif
+ pushl $GNAME(exception_handler_wrapper)
+ pushl %fs:0
+ movl %esp, %fs:0
+#endif
+
/* Alloc new frame. */
mov %esp,%ebx # The current sp marks start of new frame.
push %ebp # fp in save location S0
LsingleValue:
/* A singled value function returns here */
+#ifdef LISP_FEATURE_WIN32
+ /* Remove our SEH frame. */
+ popl %fs:0
+ add $8, %esp
+#endif
+
/* Restore the stack, in case there was a stack change. */
popl %esp # c-sp
jmp *CLOSURE_FUN_OFFSET(%eax)
SIZE(GNAME(closure_tramp))
+ .text
+ .align align_4byte,0x90
+ .globl GNAME(funcallable_instance_tramp)
+ TYPE(GNAME(funcallable_instance_tramp))
+GNAME(funcallable_instance_tramp):
+ movl FUNCALLABLE_INSTANCE_FUNCTION_OFFSET(%eax),%eax
+ /* KLUDGE: on this platform, whatever kind of function is in %rax
+ * now, the first word of it contains the address to jump to. */
+ jmp *CLOSURE_FUN_OFFSET(%eax)
+ SIZE(GNAME(funcallable_instance_tramp))
+
/*
* fun-end breakpoint magic
*/
ret
SIZE(GNAME(alloc_overflow_edi))
+
+#ifdef LISP_FEATURE_WIN32
+ /* The guts of the exception-handling system doesn't use
+ * frame pointers, which manages to throw off backtraces
+ * rather badly. So here we grab the (known-good) EBP
+ * and EIP from the exception context and use it to fake
+ * up a stack frame which will skip over the system SEH
+ * code. */
+ .align align_4byte
+ .globl GNAME(exception_handler_wrapper)
+ TYPE(GNAME(exception_handler_wrapper))
+GNAME(exception_handler_wrapper):
+ /* Context layout is: */
+ /* 7 dwords before FSA. (0x1c) */
+ /* 8 dwords and 0x50 bytes in the FSA. (0x70/0x8c) */
+ /* 4 dwords segregs. (0x10/0x9c) */
+ /* 6 dwords non-stack GPRs. (0x18/0xb4) */
+ /* EBP (at 0xb4) */
+ /* EIP (at 0xb8) */
+#define CONTEXT_EBP_OFFSET 0xb4
+#define CONTEXT_EIP_OFFSET 0xb8
+ /* some other stuff we don't care about. */
+ pushl %ebp
+ movl 0x10(%esp), %ebp /* context */
+ pushl CONTEXT_EIP_OFFSET(%ebp)
+ pushl CONTEXT_EBP_OFFSET(%ebp)
+ movl %esp, %ebp
+ pushl 0x1c(%esp)
+ pushl 0x1c(%esp)
+ pushl 0x1c(%esp)
+ pushl 0x1c(%esp)
+ call GNAME(handle_exception)
+ lea 8(%ebp), %esp
+ popl %ebp
+ ret
+ SIZE(GNAME(exception_handler_wrapper))
+#endif
+
+#ifdef LISP_FEATURE_DARWIN
+ .align align_4byte
+ .globl GNAME(call_into_lisp_tramp)
+ TYPE(GNAME(call_into_lisp_tramp))
+GNAME(call_into_lisp_tramp):
+ /* 1. build the stack frame from the block that's pointed to by ECX
+ 2. free the block
+ 3. set ECX to 0
+ 4. call the function via call_into_lisp
+ */
+ pushl 0(%ecx) /* return address */
+
+ pushl %ebp
+ movl %esp, %ebp
+
+ pushl 32(%ecx) /* eflags */
+ pushl 28(%ecx) /* EAX */
+ pushl 20(%ecx) /* ECX */
+ pushl 16(%ecx) /* EDX */
+ pushl 24(%ecx) /* EBX */
+ pushl $0 /* popal is going to ignore esp */
+ pushl %ebp /* is this right?? */
+ pushl 12(%ecx) /* ESI */
+ pushl 8(%ecx) /* EDI */
+ pushl $0 /* args for call_into_lisp */
+ pushl $0
+ pushl 4(%ecx) /* function to call */
+
+ /* free our save block */
+ pushl %ecx /* reserve sufficient space on stack for args */
+ pushl %ecx
+ andl $0xfffffff0, %esp /* align stack */
+ movl $0x40, 4(%esp)
+ movl %ecx, (%esp)
+ call GNAME(os_invalidate)
+
+ /* call call_into_lisp */
+ leal -48(%ebp), %esp
+ call GNAME(call_into_lisp)
+
+ /* Clean up our mess */
+ leal -36(%ebp), %esp
+ popal
+ popfl
+ leave
+ ret
+
+ SIZE(call_into_lisp_tramp)
+#endif
+
.align align_4byte,0x90
.globl GNAME(post_signal_tramp)
TYPE(GNAME(post_signal_tramp))
addl $12,%esp /* clear call_into_lisp args from stack */
popal /* restore registers */
popfl
+#ifdef LISP_FEATURE_DARWIN
+ /* skip two padding words */
+ addl $8,%esp
+#endif
leave
ret
SIZE(GNAME(post_signal_tramp))
-#ifdef LISP_FEATURE_WIN32
- /*
- * This is part of the funky magic for exception handling on win32.
- * see sigtrap_emulator() in win32-os.c for details.
- */
- .globl GNAME(sigtrap_trampoline)
-GNAME(sigtrap_trampoline):
- pushl %eax
- pushl %ebp
- movl %esp, %ebp
- call GNAME(sigtrap_wrapper)
- pop %eax
- pop %eax
- TRAP
- .byte trap_ContextRestore
- hlt # We should never return here.
-
- /*
- * This is part of the funky magic for exception handling on win32.
- * see handle_exception() in win32-os.c for details.
- */
- .globl GNAME(exception_trampoline)
-GNAME(exception_trampoline):
- pushl %eax
- pushl %ebp
- movl %esp, %ebp
- call GNAME(handle_win32_exception_wrapper)
- pop %eax
- pop %eax
- TRAP
- .byte trap_ContextRestore
- hlt # We should never return here.
-#endif
/* fast_bzero implementations and code to detect which implementation
* to use.