blob: fdc05b88b916f94be028eb94121748022c5cc077 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* 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
661:
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
782:
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
136weak_alias(__clone, clone)
137
138#endif