Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / sh / clone.S
blobb7d6101d16e59d04f953f7b2d71d3404a01e6545
1 /* Copyright (C) 1999-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
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.
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.
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/>.  */
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.  */
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); */
30         .text
31 ENTRY(__clone)
32         /* sanity check arguments.  */
33         tst     r4, r4
34         bt/s    0f
35          tst    r5, r5
36         bf      1f
38         bra     .Lsyscall_error
39          mov    #-EINVAL,r0
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
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
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
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
92 #endif
93         /* thread starts */
94         mov.l   @r15, r1
95         jsr     @r1
96          mov.l  @(4,r15), r4
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)
131 weak_alias (__clone, clone)