1/* Copyright (C) 1996-2022 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 <https://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#include <tcb-offsets.h>
23#define _ERRNO_H 1
24#include <bits/errno.h>
25
26/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
27 pid_t *ptid, struct user_desc *tls, pid_t *ctid); */
28
29 .text
30ENTRY(__clone)
31 @ sanity check args
32 cmp r0, #0
33 @ align sp
34 and r1, r1, #-8
35 ite ne
36 cmpne r1, #0
37 moveq r0, #-EINVAL
38 beq PLTJMP(syscall_error)
39
40 @ insert the args onto the new stack
41 str r3, [r1, #-4]!
42 str r0, [r1, #-4]!
43
44 @ do the system call
45 @ get flags
46 mov r0, r2
47 mov ip, r2
48 @ new sp is already in r1
49 push {r4, r7}
50 cfi_adjust_cfa_offset (8)
51 cfi_rel_offset (r4, 0)
52 cfi_rel_offset (r7, 4)
53 ldr r2, [sp, #8]
54 ldr r3, [sp, #12]
55 ldr r4, [sp, #16]
56 ldr r7, =SYS_ify(clone)
57 swi 0x0
58 cfi_endproc
59 cmp r0, #0
60 beq 1f
61 pop {r4, r7}
62 blt PLTJMP(C_SYMBOL_NAME(__syscall_error))
63 RETINSTR(, lr)
64
65 cfi_startproc
66PSEUDO_END (__clone)
67
681:
69 .fnstart
70 .cantunwind
71 @ pick the function arg and call address off the stack and execute
72 ldr r0, [sp, #4]
73 ldr ip, [sp], #8
74 BLX (ip)
75
76 @ and we are done, passing the return value through r0
77 ldr r7, =SYS_ify(exit)
78 swi 0x0
79
80 .fnend
81
82libc_hidden_def (__clone)
83weak_alias (__clone, clone)
84

source code of glibc/sysdeps/unix/sysv/linux/arm/clone.S