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