]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/sh/clone.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / sh / clone.S
1 /* Copyright (C) 1999-2014 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 /* clone() is even more special than fork() as it mucks with stacks
19 and invokes a function in the right context after its all over. */
20
21 #include <sysdep.h>
22 #define _ERRNO_H 1
23 #include <bits/errno.h>
24 #ifdef RESET_PID
25 #include <tcb-offsets.h>
26 #endif
27 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
28 pid_t *ptid, void *tls, pid_t *ctid); */
29
30 .text
31 ENTRY(__clone)
32 /* sanity check arguments. */
33 tst r4, r4
34 bt/s 0f
35 tst r5, r5
36 bf 1f
37 0:
38 bra .Lsyscall_error
39 mov #-EINVAL,r0
40 1:
41 /* insert the args onto the new stack */
42 mov.l r7, @-r5
43 /* save the function pointer as the 0th element */
44 mov.l r4, @-r5
45
46 /* do the system call */
47 mov r6, r4
48 mov.l @r15, r6
49 mov.l @(8,r15), r7
50 mov.l @(4,r15), r0
51 mov #+SYS_ify(clone), r3
52 trapa #0x15
53 mov r0, r1
54 mov #-12, r2
55 shad r2, r1
56 not r1, r1 // r1=0 means r0 = -1 to -4095
57 tst r1, r1 // i.e. error in linux
58 bf .Lclone_end
59 .Lsyscall_error:
60 SYSCALL_ERROR_HANDLER
61 .Lclone_end:
62 tst r0, r0
63 bt 2f
64 .Lpseudo_end:
65 rts
66 nop
67 2:
68 /* terminate the stack frame */
69 mov #0, r14
70 #ifdef RESET_PID
71 mov r4, r0
72 shlr16 r0
73 tst #1, r0 // CLONE_THREAD = (1 << 16)
74 bf/s 4f
75 mov r4, r0
76 /* new pid */
77 shlr8 r0
78 tst #1, r0 // CLONE_VM = (1 << 8)
79 bf/s 3f
80 mov #-1, r0
81 mov #+SYS_ify(getpid), r3
82 trapa #0x15
83 3:
84 stc gbr, r1
85 mov.w .Lpidoff, r2
86 add r1, r2
87 mov.l r0, @r2
88 mov.w .Ltidoff, r2
89 add r1, r2
90 mov.l r0, @r2
91 4:
92 #endif
93 /* thread starts */
94 mov.l @r15, r1
95 jsr @r1
96 mov.l @(4,r15), r4
97
98 /* we are done, passing the return value through r0 */
99 mov.l .L3, r1
100 #ifdef SHARED
101 mov.l r12, @-r15
102 sts.l pr, @-r15
103 mov r0, r4
104 mova .LG, r0
105 mov.l .LG, r12
106 add r0, r12
107 mova .L3, r0
108 add r0, r1
109 jsr @r1
110 nop
111 lds.l @r15+, pr
112 rts
113 mov.l @r15+, r12
114 #else
115 jmp @r1
116 mov r0, r4
117 #endif
118 .align 2
119 .LG:
120 .long _GLOBAL_OFFSET_TABLE_
121 .L3:
122 .long PLTJMP(C_SYMBOL_NAME(_exit))
123 #ifdef RESET_PID
124 .Lpidoff:
125 .word PID - TLS_PRE_TCB_SIZE
126 .Ltidoff:
127 .word TID - TLS_PRE_TCB_SIZE
128 #endif
129 PSEUDO_END (__clone)
130
131 weak_alias (__clone, clone)