#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"
#define GNAME(var) _##var
#endif
-#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __sun
-#define GNAMEDOLLAR(var) $##var
-#else
-#define GNAMEDOLLAR(var) $_##var
-#endif
-
-#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __sun
-#define DOLLARLITERAL(var) $##var
-#else
-#define DOLLARLITERAL(var) $##(var)
-#endif
-
/* Get the right type of alignment. Linux, FreeBSD and NetBSD (but not OpenBSD)
* want alignment in bytes.
*
#define SIZE(name)
#endif
+/*
+ * x86/darwin (as of MacOS X 10.4.5) doesn't reliably file signal
+ * handlers (SIGTRAP or Mach exception handlers) for 0xCC, wo we have
+ * to use ud2 instead. ud2 is an undefined opcode, #x0b0f, or
+ * 0F 0B in low-endian notation, that causes SIGILL to fire. We check
+ * for this instruction in the SIGILL handler and if we see it, we
+ * advance the EIP by two bytes to skip over ud2 instruction and
+ * call sigtrap_handler. */
#if defined(LISP_FEATURE_DARWIN)
#define END()
+#define TRAP ud2
#else
#define END() .end
+#define TRAP int3
#endif
.text
movl THREAD_CONTROL_STACK_START_OFFSET(%eax) ,%esp
/* don't think too hard about what happens if we get interrupted
* here */
- addl DOLLARLITERAL(THREAD_CONTROL_STACK_SIZE),%esp
+ addl $(THREAD_CONTROL_STACK_SIZE),%esp
#else
/* Win32 -really- doesn't like you switching stacks out from under it. */
movl GNAME(all_threads),%eax
TYPE(GNAME(undefined_tramp))
.byte 0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG
GNAME(undefined_tramp):
- int3
+ TRAP
.byte trap_Error
.byte 2
.byte UNDEFINED_FUN_ERROR
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
*/
movl %esp,%ebx # Setup ebx - the ofp.
subl $4,%esp # Allocate one stack slot for the return value
movl $4,%ecx # Setup ecx for one return value.
- movl DOLLARLITERAL(NIL),%edi # default second value
- movl DOLLARLITERAL(NIL),%esi # default third value
+ movl $(NIL),%edi # default second value
+ movl $(NIL),%esi # default third value
multiple_value_return:
.globl GNAME(fun_end_breakpoint_trap)
GNAME(fun_end_breakpoint_trap):
- int3
+ TRAP
.byte trap_FunEndBreakpoint
hlt # We should never return here.
TYPE(GNAME(do_pending_interrupt))
.align align_4byte,0x90
GNAME(do_pending_interrupt):
- int3
+ TRAP
.byte trap_PendingInterrupt
ret
SIZE(GNAME(do_pending_interrupt))
ret
SIZE(GNAME(alloc_overflow_edi))
+
+#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))
call GNAME(sigtrap_wrapper)
pop %eax
pop %eax
- int3
+ TRAP
.byte trap_ContextRestore
hlt # We should never return here.
call GNAME(handle_win32_exception_wrapper)
pop %eax
pop %eax
- int3
+ TRAP
.byte trap_ContextRestore
hlt # We should never return here.
#endif
* for all non-SSE2 processors.
*/
Lbase:
- movl GNAMEDOLLAR(fast_bzero_base), GNAME(fast_bzero_pointer)
+ movl $(GNAME(fast_bzero_base)), GNAME(fast_bzero_pointer)
jmp Lrestore
Lsse2:
- movl GNAMEDOLLAR(fast_bzero_sse), GNAME(fast_bzero_pointer)
+ movl $(GNAME(fast_bzero_sse)), GNAME(fast_bzero_pointer)
jmp Lrestore
Lrestore: