2 * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
4 * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
8 #include <sys/syscall.h>
11 ; Per man, libc clone( ) is as follows
13 ; int clone(int (*fn)(void *), void *child_stack,
14 ; int flags, void *arg, ...
15 ; /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */);
17 ; NOTE: I'm assuming that the last 3 args are NOT var-args and in case all
18 ; 3 are not relevant, caller will nevertheless pass those as NULL.
19 ; Current (Jul 2012) upstream powerpc/clone.S assumes similarly.
20 ; Our LTP (from 2007) doesn't seem to have tests to prove otherwise
22 ; clone syscall in kernel (ABI: CONFIG_CLONE_BACKWARDS)
24 ; int sys_clone(unsigned long clone_flags,
25 ; unsigned long newsp,
26 ; int __user *parent_tidptr,
28 ; int __user *child_tidptr)
30 #define CLONE_SETTLS 0x00080000
33 cmp r0, 0 ; @fn can't be NULL
34 cmp.ne r1, 0 ; @child_stack can't be NULL
37 ; save some of the orig args
38 ; r0 containg @fn will be clobbered AFTER syscall (with ret val)
39 ; rest are clobbered BEFORE syscall due to different arg ordering
42 mov r12, r2 ; @clone_flags
45 ; adjust libc args for syscall
47 mov r0, r2 ; libc @flags is 1st syscall arg
48 mov r2, r4 ; libc @ptid
49 mov r3, r5 ; libc @tls
50 mov r4, r6 ; libc @ctid
54 cmp r0, 0 ; return code : 0 new process, !0 parent
55 blt .L__sys_err2 ; < 0 (signed) error
56 jnz [blink] ; Parent returns
58 ; ----- child starts here ---------
60 #if defined(__UCLIBC_HAS_TLS__)
61 ; Setup TP register (since kernel doesn't do that)
62 and.f 0, r12, CLONE_SETTLS
68 ; child jumps off to @fn with @arg as argument, and returns here
72 ; falls thru to _exit() with result from @fn (already in r0)
73 b HIDDEN_JUMPTARGET(_exit)
78 ; (1) No need to make -ve kernel error code as positive errno
79 ; __syscall_error expects the -ve error code returned by kernel
80 ; (2) r0 still had orig -ve kernel error code
81 ; (3) Tail call to __syscall_error so we dont have to come back
82 ; here hence instead of jmp-n-link (reg push/pop) we do jmp
83 ; (4) No need to route __syscall_error via PLT, B is inherently
84 ; position independent
87 libc_hidden_def(clone)