]> git.saurik.com Git - apple/xnu.git/blobdiff - libsyscall/custom/__fork.s
xnu-1699.32.7.tar.gz
[apple/xnu.git] / libsyscall / custom / __fork.s
index 227812ecc13990a6edf33ae4b2599a372f1b71d0..2de3a9a28be4a40f110844b8d4b96fc4809dc02f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * 11-Jan-92  Peter King (king@next.com)
  *     Created from M68K sources
  */
  * 11-Jan-92  Peter King (king@next.com)
  *     Created from M68K sources
  */
-
-#include "SYS.h"
-
-#if defined(__ppc__) || defined(__ppc64__)
-
-/* We use mode-independent "g" opcodes such as "srgi".  These expand
- * into word operations when targeting __ppc__, and into doubleword
- * operations when targeting __ppc64__.
- */
-#include <architecture/ppc/mode_independent_asm.h>
-
-MI_ENTRY_POINT(___fork)
-    MI_PUSH_STACK_FRAME
-    
-    MI_CALL_EXTERNAL(__cthread_fork_prepare)
-    
-       li      r0,SYS_fork
-       sc                      // do the fork
-       b       Lbotch                  // error return
-
-       cmpwi   r4,0            // parent (r4==0) or child (r4==1) ?
-       beq     Lparent         // parent, since r4==0
-
-                            
-/* Here if we are the child.  */
-
-#if defined(__DYNAMIC__)
-    .cstring
-LC3:
-       .ascii  "__dyld_fork_child\0"
-    .text
-       .align 2
-       mflr    r0
-       bcl     20,31,1f
-1:     mflr    r3
-       mtlr    r0
-       addis   r3,r3,ha16(LC3-1b)
-       addi    r3,r3,lo16(LC3-1b)
-       addi    r4,r1,SF_LOCAL1
-       bl      __dyld_func_lookup
-       lg      r3,SF_LOCAL1(r1)
-       mtspr   ctr,r3
-       bctrl   
-#endif
-
-    li      r9,0
-    MI_GET_ADDRESS(r8,__current_pid)
-    stw     r9,0(r8)            // clear cached pid in child
-    
-       MI_CALL_EXTERNAL(__cthread_fork_child)
-    
-       li      r3,0        // flag for "we are the child"
-       b       Lreturn
-
-
-/* Here if we are the parent, with:
- *  r3 = child's pid
+/*
+ * All of the asm stubs in this file have been adjusted so the pre/post
+ * fork handlers and dyld fixup are done in C inside Libc. As such, Libc
+ * expects the __fork asm to fix up the return code to be -1, 0 or pid
+ * and errno if needed.
  */
  */
-Lparent:
-       stg     r3,SF_LOCAL2(r1)        // save child pid in stack
-    
-    b       Lparent_return      // clean up and return child's pid
-
-
-/* Here if the fork() syscall failed.  We're still the parent.  */
-
-Lbotch:        
 
 
-       MI_CALL_EXTERNAL(cerror)
-    li      r3,-1               // get an error return code
-       stg     r3,SF_LOCAL2(r1)        // save return code in stack
-    
-       /*
-        * We use cthread_fork_parent() to clean up after a fork error
-        * (unlock cthreads and mailloc packages) so the parent
-        * process can Malloc() after fork() errors without
-        * deadlocking.
-        */
-     
-Lparent_return:
-       MI_CALL_EXTERNAL(__cthread_fork_parent)
-       lg      r3,SF_LOCAL2(r1)    // return -1 on error, child's pid on success
-    
-Lreturn:
-    MI_POP_STACK_FRAME_AND_RETURN
+#include "SYS.h"
 
 
-#elif defined(__i386__)
+#if defined(__i386__)
 
 LEAF(___fork, 0)
        subl  $28, %esp   // Align the stack, with 16 bytes of extra padding that we'll need
 
 LEAF(___fork, 0)
        subl  $28, %esp   // Align the stack, with 16 bytes of extra padding that we'll need
-       CALL_EXTERN(__cthread_fork_prepare)
 
        movl    $ SYS_fork,%eax;        // code for fork -> eax
        UNIX_SYSCALL_TRAP               // do the system call
        jnc     L1                      // jump if CF==0
 
        CALL_EXTERN(cerror)
 
        movl    $ SYS_fork,%eax;        // code for fork -> eax
        UNIX_SYSCALL_TRAP               // do the system call
        jnc     L1                      // jump if CF==0
 
        CALL_EXTERN(cerror)
-       CALL_EXTERN(__cthread_fork_parent)
        movl    $-1,%eax
        addl    $28, %esp   // restore the stack
        ret
        movl    $-1,%eax
        addl    $28, %esp   // restore the stack
        ret
@@ -143,60 +65,23 @@ L1:
        jz      L2              // parent, since r1 == 0 in parent, 1 in child
        
        //child here...
        jz      L2              // parent, since r1 == 0 in parent, 1 in child
        
        //child here...
-#if defined(__DYNAMIC__)
-// Here on the child side of the fork we need to tell the dynamic linker that
-// we have forked.  To do this we call __dyld_fork_child in the dyanmic
-// linker.  But since we can't dynamically bind anything until this is done we
-// do this by using the private extern __dyld_func_lookup() function to get the
-// address of __dyld_fork_child (the 'C' code equivlent):
-//
-//     _dyld_func_lookup("__dyld_fork_child", &address);
-//     address();
-//
-.cstring
-LC0:
-       .ascii "__dyld_fork_child\0"
-
-.text
-       leal    0x8(%esp),%eax          // get the address where we're going to store the pointer
-       movl    %eax, 0x4(%esp)         // copy the address of the pointer
-       call    1f
-1:     popl    %eax
-       leal    LC0-1b(%eax),%eax
-       movl    %eax, 0x0(%esp)         // copy the name of the function to look up
-       call    __dyld_func_lookup
-       movl    0x8(%esp),%eax          // move the value returned in address parameter
-       call    *%eax           // call __dyld_fork_child indirectly
-#endif
-       xorl    %eax, %eax
-       REG_TO_EXTERN(%eax, __current_pid)
-       CALL_EXTERN(__cthread_fork_child)
-
        xorl    %eax,%eax       // zero eax
        xorl    %eax,%eax       // zero eax
-       addl    $28, %esp   // restore the stack
-       ret
-
-       //parent here...
+       REG_TO_EXTERN(%eax, __current_pid);
 L2:
 L2:
-       movl    %eax, 0xc(%esp)         // save pid
-
-       CALL_EXTERN_AGAIN(__cthread_fork_parent)
-       movl    0xc(%esp), %eax         // return pid
        addl    $28, %esp   // restore the stack
        addl    $28, %esp   // restore the stack
-       ret             
+       // parent ends up here skipping child portion
+       ret
 
 #elif defined(__x86_64__)
 
 LEAF(___fork, 0)
        subq  $24, %rsp   // Align the stack, plus room for local storage
 
 #elif defined(__x86_64__)
 
 LEAF(___fork, 0)
        subq  $24, %rsp   // Align the stack, plus room for local storage
-       CALL_EXTERN(__cthread_fork_prepare)
 
        movl    $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax
        UNIX_SYSCALL_TRAP               // do the system call
        jnc     L1                      // jump if CF==0
 
        CALL_EXTERN(cerror)
 
        movl    $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax
        UNIX_SYSCALL_TRAP               // do the system call
        jnc     L1                      // jump if CF==0
 
        CALL_EXTERN(cerror)
-       CALL_EXTERN(__cthread_fork_parent)
        movq    $-1, %rax
        addq    $24, %rsp   // restore the stack
        ret
        movq    $-1, %rax
        addq    $24, %rsp   // restore the stack
        ret
@@ -206,106 +91,13 @@ L1:
        jz      L2              // parent, since r1 == 0 in parent, 1 in child
        
        //child here...
        jz      L2              // parent, since r1 == 0 in parent, 1 in child
        
        //child here...
-#if defined(__DYNAMIC__)
-// Here on the child side of the fork we need to tell the dynamic linker that
-// we have forked.  To do this we call __dyld_fork_child in the dyanmic
-// linker.  But since we can't dynamically bind anything until this is done we
-// do this by using the private extern __dyld_func_lookup() function to get the
-// address of __dyld_fork_child (the 'C' code equivlent):
-//
-//     _dyld_func_lookup("__dyld_fork_child", &address);
-//     address();
-//
-.cstring
-LC0:
-       .ascii "__dyld_fork_child\0"
-
-.text
-       leaq    8(%rsp),%rsi            // get the address where we're going to store the pointer
-       leaq    LC0(%rip), %rdi         // copy the name of the function to look up
-       call    __dyld_func_lookup
-       call    *8(%rsp)                // call __dyld_fork_child indirectly
-#endif
        xorq    %rax, %rax
        xorq    %rax, %rax
-       REG_TO_EXTERN(%rax, __current_pid)
-       CALL_EXTERN(__cthread_fork_child)
-
-       xorq    %rax,%rax       // zero rax
-       addq    $24, %rsp   // restore the stack
-       ret
-
-       //parent here...
+       PICIFY(__current_pid)
+       movl    %eax,(%r11)
 L2:
 L2:
-       movl    %eax, 16(%rsp)          // save pid
-
-       CALL_EXTERN_AGAIN(__cthread_fork_parent)
-       movl    16(%rsp), %eax          // return pid
+       // parent ends up here skipping child portion
        addq    $24, %rsp   // restore the stack
        addq    $24, %rsp   // restore the stack
-       ret             
-
-#elif defined(__arm__)
-       
-       .globl  cerror
-       MI_ENTRY_POINT(_fork)
-       stmfd   sp!, {r4, r7, lr}
-       add     r7, sp, #4
-       MI_CALL_EXTERNAL(__cthread_fork_prepare)
-       mov     r1, #1                                  // prime results
-       mov     r12, #SYS_fork
-       swi     #SWI_SYSCALL                            // make the syscall
-       bcs     Lbotch                                  // error?
-       cmp     r1, #0                                  // parent (r1=0) or child(r1=1)
-       beq     Lparent
-
-       //child here...
-       MI_GET_ADDRESS(r3, __current_pid)
-       mov     r0, #0
-       str     r0, [r3]                // clear cached pid in child
-
-#if defined(__DYNAMIC__)
-// Here on the child side of the fork we need to tell the dynamic linker that
-// we have forked.  To do this we call __dyld_fork_child in the dyanmic
-// linker.  But since we can't dynamicly bind anything until this is done we
-// do this by using the private extern __dyld_func_lookup() function to get the
-// address of __dyld_fork_child (the 'C' code equivlent):
-//
-//     _dyld_func_lookup("__dyld_fork_child", &address);
-//     address();
-//
-       .cstring
-       .align 2
-LC0:
-       .ascii "__dyld_fork_child\0"
-.text
-.align 2
-       sub     sp, sp, #4                              // allocate space for the address parameter
-       mov     r1, sp                                  // get the address of the allocated space
-       ldr     r0, LP0                                 // get the name of the function to look up
-L0:    add     r0, pc, r0
-       bl      __dyld_func_lookup
-       mov     lr, pc
-       ldr     pc, [sp], #4                            // call __dyld_fork_child indirectly and pop
-#endif
-       MI_CALL_EXTERNAL(__cthread_fork_child)          // let child get ready
-       mov     r0, #0
-        ldmfd   sp!, {r4, r7, pc}
-
-Lbotch:
-       MI_CALL_EXTERNAL(cerror)                        // jump here on error
-       mov     r0,#-1                                  // set the error
-       // fall thru
-       
-Lparent:       
-       mov     r4, r0                                  // save child pid
-       MI_CALL_EXTERNAL(__cthread_fork_parent)
-       mov     r0, r4                                  // restore child pid
-       ldmfd   sp!, {r4, r7, pc}                       // pop and return
-
-       .align 2
-#if defined(__DYNAMIC__)
-LP0:
-       .long   LC0-(L0+8)
-#endif
+       ret
 
 #else
 #error Unsupported architecture
 
 #else
 #error Unsupported architecture