blob: 423a6c2f1b1f20acdc2eb36d3b070cedd72627c3 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* Copyright (C) 1999, 2000, 2003, 2004, 2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
18
19/* clone() is even more special than fork() as it mucks with stacks
20 and invokes a function in the right context after its all over. */
21
22#include <features.h>
23#include <asm/unistd.h>
24#include <sysdep.h>
25#define _ERRNO_H 1
26#include <bits/errno.h>
27#ifdef RESET_PID
28#include <tcb-offsets.h>
29#endif
30/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
31 pid_t *ptid, void *tls, pid_t *ctid); */
32
33 .text
34ENTRY(__clone)
35 /* sanity check arguments. */
36 tst r4, r4
37 bt/s 0f
38 tst r5, r5
39 bf 1f
400:
41 bra .Lsyscall_error
42 mov #-EINVAL,r0
431:
44 /* insert the args onto the new stack */
45 mov.l r7, @-r5
46 /* save the function pointer as the 0th element */
47 mov.l r4, @-r5
48
49 /* do the system call */
50 mov r6, r4
51 mov.l @r15, r6
52 mov.l @(8,r15), r7
53 mov.l @(4,r15), r0
54 mov #+SYS_ify(clone), r3
55 trapa #0x15
56 mov r0, r1
57 mov #-12, r2
58 shad r2, r1
59 not r1, r1 // r1=0 means r0 = -1 to -4095
60 tst r1, r1 // i.e. error in linux
61 bf .Lclone_end
62.Lsyscall_error:
63 SYSCALL_ERROR_HANDLER
64.Lclone_end:
65 tst r0, r0
66 bt 2f
67.Lpseudo_end:
68 rts
69 nop
702:
71 /* terminate the stack frame */
72 mov #0, r14
73#ifdef RESET_PID
74 mov r4, r0
75 shlr16 r0
76 tst #1, r0 // CLONE_THREAD = (1 << 16)
77 bf/s 4f
78 mov r4, r0
79 /* new pid */
80 shlr8 r0
81 tst #1, r0 // CLONE_VM = (1 << 8)
82 bf/s 3f
83 mov #-1, r0
84 mov #+SYS_ify(getpid), r3
85 trapa #0x15
863:
87 stc gbr, r1
88 mov.w .Lpidoff, r2
89 add r1, r2
90 mov.l r0, @r2
91 mov.w .Ltidoff, r2
92 add r1, r2
93 mov.l r0, @r2
944:
95#endif
96 /* thread starts */
97 mov.l @r15, r1
98 jsr @r1
99 mov.l @(4,r15), r4
100
101 /* we are done, passing the return value through r0 */
102 mov.l .L3, r1
103#ifdef SHARED
104 mov.l r12, @-r15
105 sts.l pr, @-r15
106 mov r0, r4
107 mova .LG, r0
108 mov.l .LG, r12
109 add r0, r12
110 mova .L3, r0
111 add r0, r1
112 jsr @r1
113 nop
114 lds.l @r15+, pr
115 rts
116 mov.l @r15+, r12
117#else
118 jmp @r1
119 mov r0, r4
120#endif
121 .align 2
122.LG:
123 .long _GLOBAL_OFFSET_TABLE_
124.L3:
125 .long PLTJMP(C_SYMBOL_NAME(_exit))
126#ifdef RESET_PID
127.Lpidoff:
128 .word PID - TLS_PRE_TCB_SIZE
129.Ltidoff:
130 .word TID - TLS_PRE_TCB_SIZE
131#endif
132PSEUDO_END (__clone)
133
134weak_alias (__clone, clone)