]> git.saurik.com Git - apple/libc.git/blob - ppc/sys/fork.s
Libc-391.5.18.tar.gz
[apple/libc.git] / ppc / sys / fork.s
1 /*
2 * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
24 *
25 * File: libc/ppc/sys/fork.s
26 *
27 * HISTORY
28 * 18-Nov-92 Ben Fathi (benf@next.com)
29 * Created from M88K sources
30 *
31 * 11-Jan-92 Peter King (king@next.com)
32 * Created from M68K sources
33 */
34
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__.
38 */
39 #include <architecture/ppc/mode_independent_asm.h>
40
41 #include "SYS.h"
42
43
44 MI_ENTRY_POINT(_fork)
45 MI_PUSH_STACK_FRAME
46
47 MI_CALL_EXTERNAL(__cthread_fork_prepare)
48
49 #if defined(__DYNAMIC__)
50 .cstring
51 LC1:
52 .ascii "__dyld_fork_prepare\0"
53 .text
54 .align 2
55 mflr r0
56 bcl 20,31,1f
57 1: mflr r3
58 mtlr r0
59 addis r3,r3,ha16(LC1-1b)
60 addi r3,r3,lo16(LC1-1b)
61 addi r4,r1,SF_LOCAL1
62 bl __dyld_func_lookup
63 lg r3,SF_LOCAL1(r1)
64 mtspr ctr,r3
65 bctrl
66 #endif
67
68 li r0,SYS_fork
69 sc // do the fork
70 b Lbotch // error return
71
72 cmpwi r4,0 // parent (r4==0) or child (r4==1) ?
73 beq Lparent // parent, since r4==0
74
75
76 /* Here if we are the child. */
77
78 #if defined(__DYNAMIC__)
79 .cstring
80 LC3:
81 .ascii "__dyld_fork_child\0"
82 .text
83 .align 2
84 mflr r0
85 bcl 20,31,1f
86 1: mflr r3
87 mtlr r0
88 addis r3,r3,ha16(LC3-1b)
89 addi r3,r3,lo16(LC3-1b)
90 addi r4,r1,SF_LOCAL1
91 bl __dyld_func_lookup
92 lg r3,SF_LOCAL1(r1)
93 mtspr ctr,r3
94 bctrl
95 #endif
96
97 li r9,0
98 MI_GET_ADDRESS(r8,__current_pid)
99 stw r9,0(r8) // clear cached pid in child
100
101 MI_CALL_EXTERNAL(__cthread_fork_child)
102
103 #if defined(__DYNAMIC__)
104 .cstring
105 LC4:
106 .ascii "__dyld_fork_child_final\0"
107 .text
108 .align 2
109 mflr r0
110 bcl 20,31,1f
111 1: mflr r3
112 mtlr r0
113 addis r3,r3,ha16(LC4-1b)
114 addi r3,r3,lo16(LC4-1b)
115 addi r4,r1,SF_LOCAL1
116 bl __dyld_func_lookup
117 lg r3,SF_LOCAL1(r1)
118 mtspr ctr,r3
119 bctrl
120 #endif
121
122 li r3,0 // flag for "we are the child"
123 b Lreturn
124
125
126 /* Here if we are the parent, with:
127 * r3 = child's pid
128 */
129 Lparent:
130 stg r3,SF_LOCAL2(r1) // save child pid in stack
131
132 #if defined(__DYNAMIC__)
133 mflr r0
134 bcl 20,31,1f
135 1: mflr r3
136 mtlr r0
137 addis r3,r3,ha16(LC2-1b)
138 addi r3,r3,lo16(LC2-1b)
139 addi r4,r1,SF_LOCAL1
140 bl __dyld_func_lookup
141 lg r3,SF_LOCAL1(r1)
142 mtspr ctr,r3
143 bctrl
144 #endif
145
146 b Lparent_return // clean up and return child's pid
147
148
149 /* Here if the fork() syscall failed. We're still the parent. */
150
151 Lbotch:
152
153 #if defined(__DYNAMIC__)
154 .cstring
155 LC2:
156 .ascii "__dyld_fork_parent\0"
157 .text
158 .align 2
159 stg r3,SF_LOCAL2(r1) // save error return in stack
160 mflr r0
161 bcl 20,31,1f
162 1: mflr r3
163 mtlr r0
164 addis r3,r3,ha16(LC2-1b)
165 addi r3,r3,lo16(LC2-1b)
166 addi r4,r1,SF_LOCAL1
167 bl __dyld_func_lookup
168 lg r3,SF_LOCAL1(r1)
169 mtspr ctr,r3
170 bctrl
171 lg r3,SF_LOCAL2(r1) // restore error code
172 #endif
173
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
177
178 /*
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
182 * deadlocking.
183 */
184
185 Lparent_return:
186 MI_CALL_EXTERNAL(__cthread_fork_parent)
187 lg r3,SF_LOCAL2(r1) // return -1 on error, child's pid on success
188
189 Lreturn:
190 MI_POP_STACK_FRAME_AND_RETURN
191