1/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2
3   The GNU C Library is free software; you can redistribute it and/or
4   modify it under the terms of the GNU Lesser General Public
5   License as published by the Free Software Foundation; either
6   version 2.1 of the License, or (at your option) any later version.
7
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   Lesser General Public License for more details.
12
13   You should have received a copy of the GNU Lesser General Public
14   License along with the GNU C Library; if not, see
15   <http://www.gnu.org/licenses/>.  */
16
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.  */
19
20#include <features.h>
21#define _ERRNO_H 1
22#include <bits/errno.h>
23#include <sys/syscall.h>
24
25/* The userland implementation is:
26   int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
27   the kernel entry is:
28   int clone (long flags, void *child_stack).
29
30   The parameters are passed in register and on the stack from userland:
31   rdi: fn
32   rsi: child_stack
33   rdx:	flags
34   rcx: arg
35   r8d:	TID field in parent
36   r9d: thread pointer
37%esp+8:	TID field in child
38
39   The kernel expects:
40   rax: system call number
41   rdi: flags
42   rsi: child_stack
43   rdx: TID field in parent
44   r10: TID field in child
45   r8:	thread pointer  */
46
47
48.text
49.global clone
50.type   clone,%function
51clone:
52	/* Sanity check arguments.  */
53	movq	$-EINVAL,%rax
54	testq	%rdi,%rdi		/* no NULL function pointers */
55	jz	__syscall_error
56	testq	%rsi,%rsi		/* no NULL stack pointers */
57	jz	__syscall_error
58
59	/* Insert the argument onto the new stack.  */
60	subq	$16,%rsi
61	movq	%rcx,8(%rsi)
62
63	/* Save the function pointer.  It will be popped off in the
64	   child in the ebx frobbing below.  */
65	movq	%rdi,0(%rsi)
66
67	/* Do the system call.  */
68	movq	%rdx, %rdi
69	movq	%r8, %rdx
70	movq	%r9, %r8
71	movq	8(%rsp), %r10
72	movl	$__NR_clone,%eax
73
74	syscall
75
76	testq	%rax,%rax
77	jl	__syscall_error
78	jz	.Lthread_start
79
80.Lpseudo_end:
81	ret
82
83.Lthread_start:
84	/* Clear the frame pointer.  The ABI suggests this be done, to mark
85	   the outermost frame obviously.  */
86	xorl	%ebp, %ebp
87
88	/* Set up arguments for the function call.  */
89	popq	%rax		/* Function to call.  */
90	popq	%rdi		/* Argument.  */
91	call	*%rax
92	/* Call exit with return value from function call. */
93	movq	%rax, %rdi
94	movl	$__NR_exit, %eax
95	syscall
96
97.size clone,.-clone
98weak_alias(clone, __clone)
99