]> git.saurik.com Git - apple/libc.git/blame - ppc/sys/fork.s
Libc-339.tar.gz
[apple/libc.git] / ppc / sys / fork.s
CommitLineData
e9ce8d39 1/*
59e0d9fe 2 * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
e9ce8d39
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
59e0d9fe
A
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
734aad71
A
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
e9ce8d39
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
734aad71
A
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.
e9ce8d39
A
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
59e0d9fe
A
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"
e9ce8d39 44
59e0d9fe
A
45
46MI_ENTRY_POINT(_fork)
47 MI_PUSH_STACK_FRAME
48
49 MI_CALL_EXTERNAL(__cthread_fork_prepare)
50
e9ce8d39 51#if defined(__DYNAMIC__)
59e0d9fe 52 .cstring
e9ce8d39
A
53LC1:
54 .ascii "__dyld_fork_prepare\0"
59e0d9fe 55 .text
e9ce8d39
A
56 .align 2
57 mflr r0
59e0d9fe 58 bcl 20,31,1f
e9ce8d39
A
591: mflr r3
60 mtlr r0
61 addis r3,r3,ha16(LC1-1b)
62 addi r3,r3,lo16(LC1-1b)
59e0d9fe
A
63 addi r4,r1,SF_LOCAL1
64 bl __dyld_func_lookup
65 lg r3,SF_LOCAL1(r1)
e9ce8d39
A
66 mtspr ctr,r3
67 bctrl
68#endif
e9ce8d39 69
59e0d9fe
A
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
e9ce8d39 80#if defined(__DYNAMIC__)
59e0d9fe 81 .cstring
e9ce8d39
A
82LC3:
83 .ascii "__dyld_fork_child\0"
59e0d9fe 84 .text
e9ce8d39
A
85 .align 2
86 mflr r0
59e0d9fe 87 bcl 20,31,1f
e9ce8d39
A
881: mflr r3
89 mtlr r0
90 addis r3,r3,ha16(LC3-1b)
91 addi r3,r3,lo16(LC3-1b)
59e0d9fe
A
92 addi r4,r1,SF_LOCAL1
93 bl __dyld_func_lookup
94 lg r3,SF_LOCAL1(r1)
e9ce8d39
A
95 mtspr ctr,r3
96 bctrl
97#endif
59e0d9fe
A
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
e9ce8d39 105#if defined(__DYNAMIC__)
59e0d9fe 106 .cstring
e9ce8d39
A
107LC4:
108 .ascii "__dyld_fork_child_final\0"
59e0d9fe 109 .text
e9ce8d39
A
110 .align 2
111 mflr r0
59e0d9fe 112 bcl 20,31,1f
e9ce8d39
A
1131: mflr r3
114 mtlr r0
115 addis r3,r3,ha16(LC4-1b)
116 addi r3,r3,lo16(LC4-1b)
59e0d9fe
A
117 addi r4,r1,SF_LOCAL1
118 bl __dyld_func_lookup
119 lg r3,SF_LOCAL1(r1)
e9ce8d39
A
120 mtspr ctr,r3
121 bctrl
122#endif
123
59e0d9fe 124 li r3,0 // flag for "we are the child"
e9ce8d39
A
125 b Lreturn
126
59e0d9fe
A
127
128/* Here if we are the parent, with:
129 * r3 = child's pid
130 */
e9ce8d39 131Lparent:
59e0d9fe
A
132 stg r3,SF_LOCAL2(r1) // save child pid in stack
133
e9ce8d39 134#if defined(__DYNAMIC__)
e9ce8d39 135 mflr r0
59e0d9fe 136 bcl 20,31,1f
e9ce8d39
A
1371: mflr r3
138 mtlr r0
139 addis r3,r3,ha16(LC2-1b)
140 addi r3,r3,lo16(LC2-1b)
59e0d9fe
A
141 addi r4,r1,SF_LOCAL1
142 bl __dyld_func_lookup
143 lg r3,SF_LOCAL1(r1)
e9ce8d39
A
144 mtspr ctr,r3
145 bctrl
146#endif
59e0d9fe
A
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. */
e9ce8d39
A
152
153Lbotch:
59e0d9fe 154
e9ce8d39 155#if defined(__DYNAMIC__)
59e0d9fe 156 .cstring
e9ce8d39
A
157LC2:
158 .ascii "__dyld_fork_parent\0"
59e0d9fe 159 .text
e9ce8d39 160 .align 2
59e0d9fe 161 stg r3,SF_LOCAL2(r1) // save error return in stack
e9ce8d39 162 mflr r0
59e0d9fe 163 bcl 20,31,1f
e9ce8d39
A
1641: mflr r3
165 mtlr r0
166 addis r3,r3,ha16(LC2-1b)
167 addi r3,r3,lo16(LC2-1b)
59e0d9fe
A
168 addi r4,r1,SF_LOCAL1
169 bl __dyld_func_lookup
170 lg r3,SF_LOCAL1(r1)
e9ce8d39
A
171 mtspr ctr,r3
172 bctrl
59e0d9fe 173 lg r3,SF_LOCAL2(r1) // restore error code
e9ce8d39 174#endif
59e0d9fe
A
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
e9ce8d39
A
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 */
59e0d9fe
A
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
e9ce8d39 193