]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/arm/clone.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / arm / clone.S
1 /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Pat Beirne <patb@corelcomputer.com>
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 /* clone() is even more special than fork() as it mucks with stacks
21    and invokes a function in the right context after its all over.  */
22
23 #define _ERRNO_H
24 #include <features.h>
25 #include <bits/errno.h>
26 #include <sys/syscall.h>
27 #include <bits/arm_asm.h>
28
29 #if defined(__NR_clone)
30 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
31
32 .text
33 .global __clone
34 .type __clone,%function
35 .align 2
36 #if defined(THUMB1_ONLY)
37 .thumb_func
38 __clone:
39         @ sanity check args
40         cmp     r0, #0
41         beq     __einval
42         cmp     r1, #0
43         beq     __einval
44
45         @ insert the args onto the new stack
46         sub     r1, r1, #8
47         str     r3, [r1, #4]
48         @ save the function pointer as the 0th element
49         str     r0, [r1]
50
51         @ do the system call
52         @ get flags
53         mov     r0, r2
54         @ new sp is already in r1
55         @ load remaining arguments off the stack
56         stmfd   sp!, {r4}
57         ldr     r2, [sp, #4]
58         ldr     r3, [sp, #8]
59         ldr     r4, [sp, #12]
60         DO_CALL (clone)
61         movs    a1, a1
62         blt     __error
63         ldmnefd sp!, {r4}
64         beq     1f
65         bx      lr
66 1:
67
68         @ pick the function arg and call address off the stack and execute
69         ldr     r0, [sp, #4]
70         ldr     r1, [sp]
71         bl      2f      @ blx r1
72
73         @ and we are done, passing the return value through r0
74         bl      HIDDEN_JUMPTARGET(_exit)
75         @ Should never return
76         b       .
77
78 2:
79         bx      r1
80
81 __einval:
82         ldr     r0, =-EINVAL
83 __error:
84         push    {r3, lr}
85         bl      __syscall_error
86         POP_RET
87 .pool
88 #else
89 __clone:
90         @ sanity check args
91         cmp     r0, #0
92         IT(te, ne)
93         cmpne   r1, #0
94         moveq   r0, #-EINVAL
95         beq     __error
96
97         @ insert the args onto the new stack
98         sub     r1, r1, #8
99         str     r3, [r1, #4]
100         @ save the function pointer as the 0th element
101         str     r0, [r1]
102
103         @ do the system call
104         @ get flags
105         mov     r0, r2
106         @ new sp is already in r1
107         @ load remaining arguments off the stack
108         stmfd   sp!, {r4}
109         ldr     r2, [sp, #4]
110         ldr     r3, [sp, #8]
111         ldr     r4, [sp, #12]
112         DO_CALL (clone)
113         movs    a1, a1
114         blt     __error
115         ldmnefd sp!, {r4}
116         IT(t, ne)
117 #if defined(__USE_BX__)
118         bxne    lr
119 #else
120         movne   pc, lr
121 #endif
122
123         @ pick the function arg and call address off the stack and execute
124         ldr     r0, [sp, #4]
125         mov     lr, pc
126         ldr     pc, [sp]
127
128         @ and we are done, passing the return value through r0
129         b       HIDDEN_JUMPTARGET(_exit)
130
131 __error:
132         b       __syscall_error
133 #endif
134
135 .size __clone,.-__clone
136 weak_alias(__clone, clone)
137
138 #endif