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