]> git.saurik.com Git - apple/libc.git/blame_incremental - ppc/sys/fork.s
Libc-339.tar.gz
[apple/libc.git] / ppc / sys / fork.s
... / ...
CommitLineData
1/*
2 * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
26 *
27 * File: libc/ppc/sys/fork.s
28 *
29 * HISTORY
30 * 18-Nov-92 Ben Fathi (benf@next.com)
31 * Created from M88K sources
32 *
33 * 11-Jan-92 Peter King (king@next.com)
34 * Created from M68K sources
35 */
36
37/* We use mode-independent "g" opcodes such as "srgi". These expand
38 * into word operations when targeting __ppc__, and into doubleword
39 * operations when targeting __ppc64__.
40 */
41#include <architecture/ppc/mode_independent_asm.h>
42
43#include "SYS.h"
44
45
46MI_ENTRY_POINT(_fork)
47 MI_PUSH_STACK_FRAME
48
49 MI_CALL_EXTERNAL(__cthread_fork_prepare)
50
51#if defined(__DYNAMIC__)
52 .cstring
53LC1:
54 .ascii "__dyld_fork_prepare\0"
55 .text
56 .align 2
57 mflr r0
58 bcl 20,31,1f
591: mflr r3
60 mtlr r0
61 addis r3,r3,ha16(LC1-1b)
62 addi r3,r3,lo16(LC1-1b)
63 addi r4,r1,SF_LOCAL1
64 bl __dyld_func_lookup
65 lg r3,SF_LOCAL1(r1)
66 mtspr ctr,r3
67 bctrl
68#endif
69
70 li r0,SYS_fork
71 sc // do the fork
72 b Lbotch // error return
73
74 cmpwi r4,0 // parent (r4==0) or child (r4==1) ?
75 beq Lparent // parent, since r4==0
76
77
78/* Here if we are the child. */
79
80#if defined(__DYNAMIC__)
81 .cstring
82LC3:
83 .ascii "__dyld_fork_child\0"
84 .text
85 .align 2
86 mflr r0
87 bcl 20,31,1f
881: mflr r3
89 mtlr r0
90 addis r3,r3,ha16(LC3-1b)
91 addi r3,r3,lo16(LC3-1b)
92 addi r4,r1,SF_LOCAL1
93 bl __dyld_func_lookup
94 lg r3,SF_LOCAL1(r1)
95 mtspr ctr,r3
96 bctrl
97#endif
98
99 li r9,0
100 MI_GET_ADDRESS(r8,__current_pid)
101 stw r9,0(r8) // clear cached pid in child
102
103 MI_CALL_EXTERNAL(__cthread_fork_child)
104
105#if defined(__DYNAMIC__)
106 .cstring
107LC4:
108 .ascii "__dyld_fork_child_final\0"
109 .text
110 .align 2
111 mflr r0
112 bcl 20,31,1f
1131: mflr r3
114 mtlr r0
115 addis r3,r3,ha16(LC4-1b)
116 addi r3,r3,lo16(LC4-1b)
117 addi r4,r1,SF_LOCAL1
118 bl __dyld_func_lookup
119 lg r3,SF_LOCAL1(r1)
120 mtspr ctr,r3
121 bctrl
122#endif
123
124 li r3,0 // flag for "we are the child"
125 b Lreturn
126
127
128/* Here if we are the parent, with:
129 * r3 = child's pid
130 */
131Lparent:
132 stg r3,SF_LOCAL2(r1) // save child pid in stack
133
134#if defined(__DYNAMIC__)
135 mflr r0
136 bcl 20,31,1f
1371: mflr r3
138 mtlr r0
139 addis r3,r3,ha16(LC2-1b)
140 addi r3,r3,lo16(LC2-1b)
141 addi r4,r1,SF_LOCAL1
142 bl __dyld_func_lookup
143 lg r3,SF_LOCAL1(r1)
144 mtspr ctr,r3
145 bctrl
146#endif
147
148 b Lparent_return // clean up and return child's pid
149
150
151/* Here if the fork() syscall failed. We're still the parent. */
152
153Lbotch:
154
155#if defined(__DYNAMIC__)
156 .cstring
157LC2:
158 .ascii "__dyld_fork_parent\0"
159 .text
160 .align 2
161 stg r3,SF_LOCAL2(r1) // save error return in stack
162 mflr r0
163 bcl 20,31,1f
1641: mflr r3
165 mtlr r0
166 addis r3,r3,ha16(LC2-1b)
167 addi r3,r3,lo16(LC2-1b)
168 addi r4,r1,SF_LOCAL1
169 bl __dyld_func_lookup
170 lg r3,SF_LOCAL1(r1)
171 mtspr ctr,r3
172 bctrl
173 lg r3,SF_LOCAL2(r1) // restore error code
174#endif
175
176 MI_CALL_EXTERNAL(cerror)
177 li r3,-1 // get an error return code
178 stg r3,SF_LOCAL2(r1) // save return code in stack
179
180 /*
181 * We use cthread_fork_parent() to clean up after a fork error
182 * (unlock cthreads and mailloc packages) so the parent
183 * process can Malloc() after fork() errors without
184 * deadlocking.
185 */
186
187Lparent_return:
188 MI_CALL_EXTERNAL(__cthread_fork_parent)
189 lg r3,SF_LOCAL2(r1) // return -1 on error, child's pid on success
190
191Lreturn:
192 MI_POP_STACK_FRAME_AND_RETURN
193