1 /* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
3 The GNU C Library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public License as
5 published by the Free Software Foundation; either version 2 of the
6 License, or (at your option) any later version.
8 The GNU C Library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public
14 License along with the GNU C Library; see the file COPYING.LIB. If not,
15 see <http://www.gnu.org/licenses/>. */
17 /* clone is even more special than fork as it mucks with stacks
18 and invokes a function in the right context after its all over. */
23 #include <bits/errno.h>
25 #include <linux/sched.h>
27 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
29 pid_t *ptid, struct user_desc *tls, pid_t *ctid)
36 /* Sanity check arguments. */
37 beqz a2, .Leinval /* no NULL function pointers */
38 beqz a3, .Leinval /* no NULL stack pointers */
40 /* a2 and a3 are candidates for destruction by system-call return
41 parameters. We don't need the stack pointer after the system
42 call. We trust that the kernel will preserve a6, a7 and a9. */
44 mov a9, a5 /* save function argument */
46 mov a7, a2 /* save function pointer */
47 mov a8, a6 /* use a8 as a temp */
50 l32i a8, a1, FRAMESIZE /* child_tid */
51 movi a2, SYS_ify(clone)
53 /* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid)
58 bltz a2, SYSCALL_ERROR_LABEL
59 beqz a2, .Lthread_start
61 /* fall through for parent */
72 #if CLONE_THREAD != 0x00010000 || CLONE_VM != 0x00000100
73 # error invalid values for CLONE_THREAD or CLONE_VM
76 /* start child thread */
77 movi a0, 0 /* terminate the stack frame */
79 #if defined(__XTENSA_WINDOWED_ABI__)
80 mov a6, a9 /* load up the 'arg' parameter */
81 callx4 a7 /* call the user's function */
83 /* Call _exit. Note that any return parameter from the user's
84 function in a6 is seen as inputs to _exit. */
85 movi a2, JUMPTARGET(_exit)
87 #elif defined(__XTENSA_CALL0_ABI__)
88 mov a2, a9 /* load up the 'arg' parameter */
89 callx0 a7 /* call the user's function */
91 /* Call _exit. Note that any return parameter from the user's
92 function in a2 is seen as inputs to _exit. */
93 movi a0, JUMPTARGET(_exit)
96 #error Unsupported Xtensa ABI
100 weak_alias (__clone, clone)