2 * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
25 * File: libc/ppc/sys/fork.s
28 * 18-Nov-92 Ben Fathi (benf@next.com)
29 * Created from M88K sources
31 * 11-Jan-92 Peter King (king@next.com)
32 * Created from M68K sources
35 /* We use mode-independent "g" opcodes such as "srgi". These expand
36 * into word operations when targeting __ppc__, and into doubleword
37 * operations when targeting __ppc64__.
39 #include <architecture/ppc/mode_independent_asm.h>
47 MI_CALL_EXTERNAL(__cthread_fork_prepare)
49 #if defined(__DYNAMIC__)
52 .ascii "__dyld_fork_prepare\0"
59 addis r3,r3,ha16(LC1-1b)
60 addi r3,r3,lo16(LC1-1b)
70 b Lbotch // error return
72 cmpwi r4,0 // parent (r4==0) or child (r4==1) ?
73 beq Lparent // parent, since r4==0
76 /* Here if we are the child. */
78 #if defined(__DYNAMIC__)
81 .ascii "__dyld_fork_child\0"
88 addis r3,r3,ha16(LC3-1b)
89 addi r3,r3,lo16(LC3-1b)
98 MI_GET_ADDRESS(r8,__current_pid)
99 stw r9,0(r8) // clear cached pid in child
101 MI_CALL_EXTERNAL(__cthread_fork_child)
103 #if defined(__DYNAMIC__)
106 .ascii "__dyld_fork_child_final\0"
113 addis r3,r3,ha16(LC4-1b)
114 addi r3,r3,lo16(LC4-1b)
116 bl __dyld_func_lookup
122 li r3,0 // flag for "we are the child"
126 /* Here if we are the parent, with:
130 stg r3,SF_LOCAL2(r1) // save child pid in stack
132 #if defined(__DYNAMIC__)
137 addis r3,r3,ha16(LC2-1b)
138 addi r3,r3,lo16(LC2-1b)
140 bl __dyld_func_lookup
146 b Lparent_return // clean up and return child's pid
149 /* Here if the fork() syscall failed. We're still the parent. */
153 #if defined(__DYNAMIC__)
156 .ascii "__dyld_fork_parent\0"
159 stg r3,SF_LOCAL2(r1) // save error return in stack
164 addis r3,r3,ha16(LC2-1b)
165 addi r3,r3,lo16(LC2-1b)
167 bl __dyld_func_lookup
171 lg r3,SF_LOCAL2(r1) // restore error code
174 MI_CALL_EXTERNAL(cerror)
175 li r3,-1 // get an error return code
176 stg r3,SF_LOCAL2(r1) // save return code in stack
179 * We use cthread_fork_parent() to clean up after a fork error
180 * (unlock cthreads and mailloc packages) so the parent
181 * process can Malloc() after fork() errors without
186 MI_CALL_EXTERNAL(__cthread_fork_parent)
187 lg r3,SF_LOCAL2(r1) // return -1 on error, child's pid on success
190 MI_POP_STACK_FRAME_AND_RETURN