1.0.10.36: support for Darwin versions that support __DARWIN_UNIX03
authorCyrus Harmon <ch-sbcl@bobobeach.com>
Mon, 8 Oct 2007 01:46:30 +0000 (01:46 +0000)
committerCyrus Harmon <ch-sbcl@bobobeach.com>
Mon, 8 Oct 2007 01:46:30 +0000 (01:46 +0000)
 * 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

13 files changed:
contrib/sb-bsd-sockets/name-service.lisp
contrib/sb-bsd-sockets/tests.lisp
src/code/foreign.lisp
src/compiler/x86-64/c-call.lisp
src/runtime/darwin-os.h
src/runtime/x86-64-arch.c
src/runtime/x86-64-darwin-os.c
src/runtime/x86-64-darwin-os.h
src/runtime/x86-arch.c
src/runtime/x86-darwin-os.c
src/runtime/x86-darwin-os.h
tools-for-build/ldso-stubs.lisp
version.lisp-expr

index b5f9755..ff9279b 100644 (file)
@@ -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)))
index 66f8707..de2a441 100644 (file)
     ;; 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)
     ;; 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)
index 430614e..805c5ab 100644 (file)
   (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
index 32fb566..807e547 100644 (file)
               (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))
index b93fa2b..bc39a33 100644 (file)
 #if defined(LISP_FEATURE_X86)
 #include <sys/ucontext.h>
 #include <sys/_types.h>
+#if __DARWIN_UNIX03
+typedef struct __darwin_ucontext os_context_t;
+#else
 typedef struct ucontext os_context_t;
+#endif
+
 
 #else
 #include <ucontext.h>
index 611bee6..6a6e53b 100644 (file)
@@ -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
index 20cbce1..c1055c0 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 
+#if __DARWIN_UNIX03
+#include <sys/_structs.h>
+#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"
index d68693d..4de6bf4 100644 (file)
@@ -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 */
index a871962..d6150dd 100644 (file)
@@ -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
index 0c46dff..97d3999 100644 (file)
@@ -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;
index aa2710c..79dea31 100644 (file)
@@ -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 */
index 0360b1d..5e1abdb 100644 (file)
@@ -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: ;                            "
 
index 9c31178..1e67aca 100644 (file)
@@ -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"