X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-64-darwin-os.c;h=ed8abbbf16b581eb032dc9319032e80822cb7710;hb=95591ed483dbb8c0846c129953acac1554f28809;hp=20cbce1340f73c24e74b8843c56b300835416385;hpb=0f234877047c56ca945fe54e9e77a9cc2c8141cb;p=sbcl.git diff --git a/src/runtime/x86-64-darwin-os.c b/src/runtime/x86-64-darwin-os.c index 20cbce1..ed8abbb 100644 --- a/src/runtime/x86-64-darwin-os.c +++ b/src/runtime/x86-64-darwin-os.c @@ -1,4 +1,3 @@ - #ifdef LISP_FEATURE_SB_THREAD #include #include @@ -25,6 +24,38 @@ #include #include +#if __DARWIN_UNIX03 +#include +#endif + +#if __DARWIN_UNIX03 + +typedef struct __darwin_ucontext darwin_ucontext; +typedef struct __darwin_mcontext64 darwin_mcontext; + +#define rip __rip +#define rsp __rsp +#define rbp __rbp +#define rax __rax +#define rbx __rbx +#define rcx __rcx +#define rdx __rdx +#define rsi __rsi +#define rdi __rdi +#define r8 __r8 +#define r9 __r9 +#define faultvaddr __faultvaddr +#define ss __ss +#define es __es +#define fs __fs + +#else + +typedef struct ucontext darwin_ucontext; +typedef struct mcontext darwin_mcontext; + +#endif + #ifdef LISP_FEATURE_SB_THREAD pthread_mutex_t mach_exception_lock = PTHREAD_MUTEX_INITIALIZER; #endif @@ -33,9 +64,10 @@ pthread_mutex_t mach_exception_lock = PTHREAD_MUTEX_INITIALIZER; kern_return_t mach_thread_init(mach_port_t thread_exception_port); -void sigill_handler(int signal, siginfo_t *siginfo, void *void_context); -void sigtrap_handler(int signal, siginfo_t *siginfo, void *void_context); -void memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context); +void sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context); +void sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context); +void memory_fault_handler(int signal, siginfo_t *siginfo, + os_context_t *context); /* exc_server handles mach exception messages from the kernel and * calls catch exception raise. We use the system-provided @@ -47,7 +79,7 @@ extern boolean_t exc_server(); /* This executes in the faulting thread as part of the signal * emulation. It is passed a context with the uc_mcontext field * pointing to a valid block of memory. */ -void build_fake_signal_context(struct ucontext *context, +void build_fake_signal_context(darwin_ucontext *context, x86_thread_state64_t *thread_state, x86_float_state64_t *float_state) { pthread_sigmask(0, NULL, &context->uc_sigmask); @@ -59,7 +91,7 @@ void build_fake_signal_context(struct ucontext *context, * emulation. It is effectively the inverse operation from above. */ void update_thread_state_from_context(x86_thread_state64_t *thread_state, x86_float_state64_t *float_state, - struct ucontext *context) { + darwin_ucontext *context) { *thread_state = context->uc_mcontext->ss; *float_state = context->uc_mcontext->fs; pthread_sigmask(SIG_SETMASK, &context->uc_sigmask, NULL); @@ -184,11 +216,11 @@ void signal_emulation_wrapper(x86_thread_state64_t *thread_state, * context (and regs just for symmetry). */ - struct ucontext *context; - struct mcontext *regs; + darwin_ucontext *context; + darwin_mcontext *regs; - context = (struct ucontext*) os_validate(0, sizeof(struct ucontext)); - regs = (struct mcontext*) os_validate(0, sizeof(struct mcontext)); + context = (darwin_ucontext *) os_validate(0, sizeof(darwin_ucontext)); + regs = (darwin_mcontext*) os_validate(0, sizeof(darwin_mcontext)); context->uc_mcontext = regs; /* when BSD signals are fired, they mask they signals in sa_mask @@ -201,14 +233,14 @@ void signal_emulation_wrapper(x86_thread_state64_t *thread_state, build_fake_signal_context(context, thread_state, float_state); - block_blockable_signals(); + block_blockable_signals(0, 0); handler(signal, siginfo, context); update_thread_state_from_context(thread_state, float_state, context); - os_invalidate((os_vm_address_t)context, sizeof(struct ucontext)); - os_invalidate((os_vm_address_t)regs, sizeof(struct mcontext)); + os_invalidate((os_vm_address_t)context, sizeof(darwin_ucontext)); + os_invalidate((os_vm_address_t)regs, sizeof(darwin_mcontext)); /* Trap to restore the signal context. */ asm volatile ("mov %0, %%rax; mov %1, %%rbx; .quad 0xffffffffffff0b0f" @@ -245,19 +277,17 @@ void dump_context(x86_thread_state64_t *context) #endif void -control_stack_exhausted_handler(int signal, siginfo_t *siginfo, void *void_context) { - os_context_t *context = arch_os_get_context(&void_context); - +control_stack_exhausted_handler(int signal, siginfo_t *siginfo, + os_context_t *context) { + unblock_signals_in_context_and_maybe_warn(context); arrange_return_to_lisp_function - (context, SymbolFunction(CONTROL_STACK_EXHAUSTED_ERROR)); + (context, StaticSymbolFunction(CONTROL_STACK_EXHAUSTED_ERROR)); } void -undefined_alien_handler(int signal, siginfo_t *siginfo, void *void_context) { - os_context_t *context = arch_os_get_context(&void_context); - +undefined_alien_handler(int signal, siginfo_t *siginfo, os_context_t *context) { arrange_return_to_lisp_function - (context, SymbolFunction(UNDEFINED_ALIEN_VARIABLE_ERROR)); + (context, StaticSymbolFunction(UNDEFINED_ALIEN_VARIABLE_ERROR)); } kern_return_t @@ -322,11 +352,14 @@ catch_exception_raise(mach_port_t exception_port, * protection so the error handler has some headroom, protect the * previous page so that we can catch returns from the guard page * and restore it. */ - protect_control_stack_guard_page_thread(0, th); - protect_control_stack_return_guard_page_thread(1, th); + lower_thread_control_stack_guard_page(th); backup_thread_state = thread_state; open_stack_allocation(&thread_state); + /* Reserve a 256 byte zone for signal handlers + * to use on the interrupted thread stack. + */ + stack_allocate(&thread_state, 256); /* Save thread state */ target_thread_state = @@ -360,13 +393,13 @@ catch_exception_raise(mach_port_t exception_port, * unprotect this one. This works even if we somehow missed * the return-guard-page, and hit it on our way to new * exhaustion instead. */ - protect_control_stack_guard_page_thread(1, th); - protect_control_stack_return_guard_page_thread(0, th); + reset_thread_control_stack_guard_page(th); } else if (addr >= undefined_alien_address && addr < undefined_alien_address + os_vm_page_size) { backup_thread_state = thread_state; open_stack_allocation(&thread_state); + stack_allocate(&thread_state, 256); /* Save thread state */ target_thread_state = @@ -396,6 +429,7 @@ catch_exception_raise(mach_port_t exception_port, backup_thread_state = thread_state; open_stack_allocation(&thread_state); + stack_allocate(&thread_state, 256); /* Save thread state */ target_thread_state = @@ -472,6 +506,7 @@ catch_exception_raise(mach_port_t exception_port, backup_thread_state = thread_state; open_stack_allocation(&thread_state); + stack_allocate(&thread_state, 256); /* Save thread state */ target_thread_state = @@ -542,7 +577,7 @@ mach_exception_handler(void *port) /* mach_msg_server should never return, but it should dispatch mach * exceptions to our catch_exception_raise function */ - abort(); + lose("mach_msg_server returned"); } /* Sets up the thread that will listen for mach exceptions. note that