From: Cyrus Harmon Date: Mon, 8 Oct 2007 01:46:30 +0000 (+0000) Subject: 1.0.10.36: support for Darwin versions that support __DARWIN_UNIX03 X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=127fd3d2fb843c6bb7ad0763e143d81877e760e8;p=sbcl.git 1.0.10.36: support for Darwin versions that support __DARWIN_UNIX03 * on some versions of darwin symbols without a leading _ are dropped by the linker. Use a leading _ on Darwin ldso_stub functions. * Add a FIXME about 128-bit integeer passing being broken on x86-64 * _DARWIN_UNIX03 support ** os_context_t is now __darwin_ucontext ** eip -> __eip (and friends) - use macro hackery EIP etc... ** use darwin_ucontext/darwin_mcontext instead of struct ucontext/mcontext where appropriate. ** struct ucontext -> os_context_t where appropriate * allow socket-error for the aceptable errors in inet-socket error test cases * Add a fix me about a rumored OS bug fix that in name-service tests --- diff --git a/contrib/sb-bsd-sockets/name-service.lisp b/contrib/sb-bsd-sockets/name-service.lisp index b5f9755..ff9279b 100644 --- a/contrib/sb-bsd-sockets/name-service.lisp +++ b/contrib/sb-bsd-sockets/name-service.lisp @@ -35,6 +35,7 @@ (#.sockint::af-inet ;; CLH: Work around x86-64 darwin bug here. ;; The length is reported as 8, when it should be 4. + ;; FIXME: this is rumored to be fix in 10.5 #+(and darwin x86-64) (progn (assert (or (= length 4) (= length 8))) diff --git a/contrib/sb-bsd-sockets/tests.lisp b/contrib/sb-bsd-sockets/tests.lisp index 66f8707..de2a441 100644 --- a/contrib/sb-bsd-sockets/tests.lisp +++ b/contrib/sb-bsd-sockets/tests.lisp @@ -45,7 +45,13 @@ ;; way to check the condition stuff on its own, which is a shame (handler-case (make-instance 'inet-socket :type :stream :protocol (get-protocol-by-name "udp")) - ((or socket-type-not-supported-error protocol-not-supported-error) (c) + ;; CLH FIXME! some versions of darwin just return a socket error + ;; here, not socket-type-not-supported-error or + ;; protocol-not-supported-error. + ((or #+darwin socket-error + socket-type-not-supported-error + protocol-not-supported-error) + (c) (declare (ignorable c)) t) (:no-error nil)) t) @@ -54,7 +60,14 @@ ;; same again with keywords (handler-case (make-instance 'inet-socket :type :stream :protocol :udp) - ((or protocol-not-supported-error socket-type-not-supported-error) (c) + ;; CLH FIXME! some versions of darwin just return a socket error + ;; here, not socket-type-not-supported-error or + ;; protocol-not-supported-error. + ((or + #+darwin socket-error + protocol-not-supported-error + socket-type-not-supported-error) + (c) (declare (ignorable c)) t) (:no-error nil)) t) diff --git a/src/code/foreign.lisp b/src/code/foreign.lisp index 430614e..805c5ab 100644 --- a/src/code/foreign.lisp +++ b/src/code/foreign.lisp @@ -34,7 +34,10 @@ (let ((extern (extern-alien-name name))) (values (or (gethash extern table) - (gethash (concatenate 'base-string "ldso_stub__" extern) table))))) + (gethash (concatenate 'base-string + #!+(and darwin (or x86 x86-64)) "_ldso_stub__" + #!-(and darwin (or x86 x86-64)) "ldso_stub__" + extern) table))))) (defun find-foreign-symbol-address (name) "Returns the address of the foreign symbol NAME, or NIL. Does not enter the diff --git a/src/compiler/x86-64/c-call.lisp b/src/compiler/x86-64/c-call.lisp index 32fb566..807e547 100644 --- a/src/compiler/x86-64/c-call.lisp +++ b/src/compiler/x86-64/c-call.lisp @@ -150,6 +150,10 @@ (lambda-vars arg) (cond ((and (alien-integer-type-p type) (> (sb!alien::alien-integer-type-bits type) 64)) + ;; CLH: FIXME! This should really be + ;; #xffffffffffffffff. nyef says: "Passing + ;; 128-bit integers to ALIEN functions on x86-64 + ;; believed to be broken." (new-args `(logand ,arg #xffffffff)) (new-args `(ash ,arg -64)) (new-arg-types (parse-alien-type '(unsigned 64) env)) diff --git a/src/runtime/darwin-os.h b/src/runtime/darwin-os.h index b93fa2b..bc39a33 100644 --- a/src/runtime/darwin-os.h +++ b/src/runtime/darwin-os.h @@ -16,7 +16,12 @@ #if defined(LISP_FEATURE_X86) #include #include +#if __DARWIN_UNIX03 +typedef struct __darwin_ucontext os_context_t; +#else typedef struct ucontext os_context_t; +#endif + #else #include diff --git a/src/runtime/x86-64-arch.c b/src/runtime/x86-64-arch.c index 611bee6..6a6e53b 100644 --- a/src/runtime/x86-64-arch.c +++ b/src/runtime/x86-64-arch.c @@ -63,7 +63,11 @@ context_eflags_addr(os_context_t *context) #elif defined __FreeBSD__ return &context->uc_mcontext.mc_rflags; #elif defined LISP_FEATURE_DARWIN +#if defined __DARWIN_UNIX03 + return &context->uc_mcontext->__ss.__rflags; +#else return &context->uc_mcontext->ss.rflags; +#endif #elif defined __OpenBSD__ return &context->sc_eflags; #else diff --git a/src/runtime/x86-64-darwin-os.c b/src/runtime/x86-64-darwin-os.c index 20cbce1..c1055c0 100644 --- a/src/runtime/x86-64-darwin-os.c +++ b/src/runtime/x86-64-darwin-os.c @@ -25,6 +25,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 @@ -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 @@ -207,8 +239,8 @@ void signal_emulation_wrapper(x86_thread_state64_t *thread_state, 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" diff --git a/src/runtime/x86-64-darwin-os.h b/src/runtime/x86-64-darwin-os.h index d68693d..4de6bf4 100644 --- a/src/runtime/x86-64-darwin-os.h +++ b/src/runtime/x86-64-darwin-os.h @@ -10,7 +10,11 @@ static inline os_context_t *arch_os_get_context(void **void_context) return (os_context_t *) *void_context; } +#if defined __DARWIN_UNIX03 +#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->__ss.__##stem +#else #define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->ss.stem +#endif #define DARWIN_FIX_CONTEXT(context) #endif /* _X86_64_DARWIN_OS_H */ diff --git a/src/runtime/x86-arch.c b/src/runtime/x86-arch.c index a871962..d6150dd 100644 --- a/src/runtime/x86-arch.c +++ b/src/runtime/x86-arch.c @@ -66,7 +66,7 @@ context_eflags_addr(os_context_t *context) #elif defined __OpenBSD__ return &context->sc_eflags; #elif defined LISP_FEATURE_DARWIN - return (int *)(&context->uc_mcontext->ss.eflags); + return (int *)(&context->uc_mcontext->SS.EFLAGS); #elif defined __NetBSD__ return &(context->uc_mcontext.__gregs[_REG_EFL]); #elif defined LISP_FEATURE_WIN32 diff --git a/src/runtime/x86-darwin-os.c b/src/runtime/x86-darwin-os.c index 0c46dff..97d3999 100644 --- a/src/runtime/x86-darwin-os.c +++ b/src/runtime/x86-darwin-os.c @@ -130,39 +130,39 @@ 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(os_context_t *context, x86_thread_state32_t *thread_state, x86_float_state32_t *float_state) { pthread_sigmask(0, NULL, &context->uc_sigmask); - context->uc_mcontext->ss = *thread_state; - context->uc_mcontext->fs = *float_state; + context->uc_mcontext->SS = *thread_state; + context->uc_mcontext->FS = *float_state; } /* This executes in the faulting thread as part of the signal * emulation. It is effectively the inverse operation from above. */ void update_thread_state_from_context(x86_thread_state32_t *thread_state, x86_float_state32_t *float_state, - struct ucontext *context) { - *thread_state = context->uc_mcontext->ss; - *float_state = context->uc_mcontext->fs; + os_context_t *context) { + *thread_state = context->uc_mcontext->SS; + *float_state = context->uc_mcontext->FS; pthread_sigmask(SIG_SETMASK, &context->uc_sigmask, NULL); } /* Modify a context to push new data on its stack. */ -void push_context(u32 data, x86_thread_state32_t *context) +void push_context(u32 data, x86_thread_state32_t *thread_state) { u32 *stack_pointer; - stack_pointer = (u32*) context->esp; + stack_pointer = (u32*) thread_state->ESP; *(--stack_pointer) = data; - context->esp = (unsigned int) stack_pointer; + thread_state->ESP = (unsigned int) stack_pointer; } -void align_context_stack(x86_thread_state32_t *context) +void align_context_stack(x86_thread_state32_t *thread_state) { /* 16byte align the stack (provided that the stack is, as it * should be, 4byte aligned. */ - while (context->esp & 15) push_context(0, context); + while (thread_state->ESP & 15) push_context(0, thread_state); } /* Stack allocation starts with a context that has a mod-4 ESP value @@ -172,29 +172,29 @@ void align_context_stack(x86_thread_state32_t *context) * EBP, pops EBP, and returns. */ asm("_stack_allocation_recover: movl %ebp, %esp; popl %ebp; ret;"); -void open_stack_allocation(x86_thread_state32_t *context) +void open_stack_allocation(x86_thread_state32_t *thread_state) { void stack_allocation_recover(void); - push_context(context->eip, context); - push_context(context->ebp, context); - context->ebp = context->esp; - context->eip = (unsigned int) stack_allocation_recover; + push_context(thread_state->EIP, thread_state); + push_context(thread_state->EBP, thread_state); + thread_state->EBP = thread_state->ESP; + thread_state->EIP = (unsigned int) stack_allocation_recover; - align_context_stack(context); + align_context_stack(thread_state); } /* Stack allocation of data starts with a context with a mod-16 ESP * value and reserves some space on it by manipulating the ESP * register. */ -void *stack_allocate(x86_thread_state32_t *context, size_t size) +void *stack_allocate(x86_thread_state32_t *thread_state, size_t size) { /* round up size to 16byte multiple */ size = (size + 15) & -16; - context->esp = ((u32)context->esp) - size; + thread_state->ESP = ((u32)thread_state->ESP) - size; - return (void *)context->esp; + return (void *)thread_state->ESP; } /* Arranging to invoke a C function is tricky, as we have to assume @@ -202,7 +202,7 @@ void *stack_allocate(x86_thread_state32_t *context, size_t size) * alignment requirements. The simplest way to arrange this, * actually, is to open a new stack allocation. * WARNING!!! THIS DOES NOT PRESERVE REGISTERS! */ -void call_c_function_in_context(x86_thread_state32_t *context, +void call_c_function_in_context(x86_thread_state32_t *thread_state, void *function, int nargs, ...) @@ -212,25 +212,25 @@ void call_c_function_in_context(x86_thread_state32_t *context, u32 *stack_pointer; /* Set up to restore stack on exit. */ - open_stack_allocation(context); + open_stack_allocation(thread_state); /* Have to keep stack 16byte aligned on x86/darwin. */ for (i = (3 & -nargs); i; i--) { - push_context(0, context); + push_context(0, thread_state); } - context->esp = ((u32)context->esp) - nargs * 4; - stack_pointer = (u32 *)context->esp; + thread_state->ESP = ((u32)thread_state->ESP) - nargs * 4; + stack_pointer = (u32 *)thread_state->ESP; va_start(ap, nargs); for (i = 0; i < nargs; i++) { - //push_context(va_arg(ap, u32), context); + //push_context(va_arg(ap, u32), thread_state); stack_pointer[i] = va_arg(ap, u32); } va_end(ap); - push_context(context->eip, context); - context->eip = (unsigned int) function; + push_context(thread_state->EIP, thread_state); + thread_state->EIP = (unsigned int) function; } void signal_emulation_wrapper(x86_thread_state32_t *thread_state, @@ -253,11 +253,19 @@ void signal_emulation_wrapper(x86_thread_state32_t *thread_state, * context (and regs just for symmetry). */ - struct ucontext *context; + os_context_t *context; +#if __DARWIN_UNIX03 + struct __darwin_mcontext32 *regs; +#else struct mcontext *regs; +#endif - context = (struct ucontext*) os_validate(0, sizeof(struct ucontext)); + context = (os_context_t*) os_validate(0, sizeof(os_context_t)); +#if __DARWIN_UNIX03 + regs = (struct __darwin_mcontext32*) os_validate(0, sizeof(struct __darwin_mcontext32)); +#else regs = (struct mcontext*) os_validate(0, sizeof(struct mcontext)); +#endif context->uc_mcontext = regs; /* when BSD signals are fired, they mask they signals in sa_mask @@ -276,8 +284,12 @@ void signal_emulation_wrapper(x86_thread_state32_t *thread_state, 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)context, sizeof(os_context_t)); +#if __DARWIN_UNIX03 + os_invalidate((os_vm_address_t)regs, sizeof(struct __darwin_mcontext32)); +#else os_invalidate((os_vm_address_t)regs, sizeof(struct mcontext)); +#endif /* Trap to restore the signal context. */ asm volatile ("movl %0, %%eax; movl %1, %%ebx; .long 0xffff0b0f" @@ -337,26 +349,30 @@ void call_handler_on_thread(mach_port_t thread, } #if defined DUMP_CONTEXT -void dump_context(x86_thread_state32_t *context) +void dump_context(x86_thread_state32_t *thread_state) { int i; u32 *stack_pointer; printf("eax: %08lx ecx: %08lx edx: %08lx ebx: %08lx\n", - context->eax, context->ecx, context->edx, context->ebx); + thread_state->EAX, thread_state->ECX, thread_state->EDX, thread_state->EAX); printf("esp: %08lx ebp: %08lx esi: %08lx edi: %08lx\n", - context->esp, context->ebp, context->esi, context->edi); + thread_state->ESP, thread_state->EBP, thread_state->ESI, thread_state->EDI); printf("eip: %08lx eflags: %08lx\n", - context->eip, context->eflags); + thread_state->EIP, thread_state->EFLAGS); printf("cs: %04hx ds: %04hx es: %04hx " "ss: %04hx fs: %04hx gs: %04hx\n", - context->cs, context->ds, context->es, - context->ss, context->fs, context->gs); - - stack_pointer = (u32 *)context->esp; + thread_state->CS, + thread_state->DS, + thread_state->ES, + thread_state->SS, + thread_state->FS, + thread_state->GS); + + stack_pointer = (u32 *)thread_state->ESP; for (i = 0; i < 48; i+=4) { printf("%08x: %08x %08x %08x %08x\n", - context->esp + (i * 4), + thread_state->ESP + (i * 4), stack_pointer[i], stack_pointer[i+1], stack_pointer[i+2], @@ -469,7 +485,7 @@ catch_exception_raise(mach_port_t exception_port, break; } /* Check if UD2 instruction */ - if (*(unsigned short *)thread_state.eip != 0x0b0f) { + if (*(unsigned short *)thread_state.EIP != 0x0b0f) { /* KLUDGE: There are two ways we could get here: * 1) We're executing data and we've hit some truly * illegal opcode, of which there are a few, see @@ -485,26 +501,26 @@ catch_exception_raise(mach_port_t exception_port, */ static mach_port_t last_thread; static unsigned int last_eip; - if (last_thread == thread && last_eip == thread_state.eip) + if (last_thread == thread && last_eip == thread_state.EIP) ret = KERN_INVALID_RIGHT; else ret = KERN_SUCCESS; last_thread = thread; - last_eip = thread_state.eip; + last_eip = thread_state.EIP; break; } /* Skip the trap code */ - thread_state.eip += 2; + thread_state.EIP += 2; /* Return from handler? */ - if (*(unsigned short *)thread_state.eip == 0xffff) { + if (*(unsigned short *)thread_state.EIP == 0xffff) { if ((ret = thread_set_state(thread, x86_THREAD_STATE32, - (thread_state_t)thread_state.eax, + (thread_state_t)thread_state.EAX, x86_THREAD_STATE32_COUNT)) != KERN_SUCCESS) lose("thread_set_state (x86_THREAD_STATE32) failed %d\n", ret); if ((ret = thread_set_state(thread, x86_FLOAT_STATE32, - (thread_state_t)thread_state.ebx, + (thread_state_t)thread_state.EBX, x86_FLOAT_STATE32_COUNT)) != KERN_SUCCESS) lose("thread_set_state (x86_FLOAT_STATE32) failed %d\n", ret); break; diff --git a/src/runtime/x86-darwin-os.h b/src/runtime/x86-darwin-os.h index aa2710c..79dea31 100644 --- a/src/runtime/x86-darwin-os.h +++ b/src/runtime/x86-darwin-os.h @@ -16,7 +16,55 @@ static inline os_context_t *arch_os_get_context(void **void_context) void set_data_desc_size(data_desc_t* desc, unsigned long size); void set_data_desc_addr(data_desc_t* desc, void* addr); -#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->ss.stem #define DARWIN_FIX_CONTEXT(context) +/* As of XCode 3.0, the field names for the thread state have changed + * and now are prepended with __. Use some #define hackery to deal + * with this. __DARWIN_UNIX03 seems to be a good test to see if we + * need the new style field names. + */ +#if __DARWIN_UNIX03 + +#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->__ss.__##stem +#define EIP __eip +#define ESP __esp +#define EBP __ebp +#define EAX __eax +#define EBX __ebx +#define ECX __ecx +#define EDX __edx +#define ESI __esi +#define EDI __edi +#define EFLAGS __eflags +#define CS __cs +#define DS __ds +#define ES __es +#define FS __fs +#define SS __ss +#define GS __gs + +#else + +#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->ss.stem +#define EIP eip +#define ESP esp +#define EBP ebp +#define EAX eax +#define EBX ebx +#define ECX ecx +#define EDX edx +#define ESI esi +#define EDI edi +#define EFLAGS eflags +#define CS cs +#define DS ds +#define ES es +#define FS fs +#define SS ss +#define GS gs + +#endif /* __DARWIN_UNIX03 */ + + + #endif /* _X86_DARWIN_OS_H */ diff --git a/tools-for-build/ldso-stubs.lisp b/tools-for-build/ldso-stubs.lisp index 0360b1d..5e1abdb 100644 --- a/tools-for-build/ldso-stubs.lisp +++ b/tools-for-build/ldso-stubs.lisp @@ -117,8 +117,8 @@ ldso_stub__ ## fct ## $lazy_ptr: @\\ #define LDSO_STUBIFY(fct) \\ .text ; \\ .align 4 ; \\ -.globl ldso_stub___ ## fct ; \\ -ldso_stub___ ## fct: ; \\ +.globl _ldso_stub___ ## fct ; \\ +_ldso_stub___ ## fct: ; \\ jmp L ## fct ## $stub ; \\ .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 ; \\ L ## fct ## $stub: ; \\ @@ -134,8 +134,8 @@ L ## fct ## $stub: ; \\ #!+(and darwin x86-64) " #define LDSO_STUBIFY(fct) \\ .align 4 ; \\ -.globl ldso_stub___ ## fct ; \\ -ldso_stub___ ## fct: ; \\ +.globl _ldso_stub___ ## fct ; \\ +_ldso_stub___ ## fct: ; \\ jmp _ ## fct ; \\ .L ## fct ## e1: ; " diff --git a/version.lisp-expr b/version.lisp-expr index 9c31178..1e67aca 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.10.35" +"1.0.10.36"