]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/x86_64/clone.S
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / x86_64 / clone.S
1 /* Copyright (C) 2001, 2002, 2003, 2004, 2005 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    <http://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 <features.h>
22 #define _ERRNO_H 1
23 #include <bits/errno.h>
24 #include <sys/syscall.h>
25
26 #define CLONE_VM        0x00000100
27 #define CLONE_THREAD    0x00010000
28
29 /* The userland implementation is:
30    int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
31    the kernel entry is:
32    int clone (long flags, void *child_stack).
33
34    The parameters are passed in register and on the stack from userland:
35    rdi: fn
36    rsi: child_stack
37    rdx: flags
38    rcx: arg
39    r8d: TID field in parent
40    r9d: thread pointer
41 %esp+8: TID field in child
42
43    The kernel expects:
44    rax: system call number
45    rdi: flags
46    rsi: child_stack
47    rdx: TID field in parent
48    r10: TID field in child
49    r8:  thread pointer  */
50
51
52 .text
53 .global clone
54 .type   clone,%function
55 clone:
56         /* Sanity check arguments.  */
57         movq    $-EINVAL,%rax
58         testq   %rdi,%rdi               /* no NULL function pointers */
59         jz      __syscall_error
60         testq   %rsi,%rsi               /* no NULL stack pointers */
61         jz      __syscall_error
62
63         /* Insert the argument onto the new stack.  */
64         subq    $16,%rsi
65         movq    %rcx,8(%rsi)
66
67         /* Save the function pointer.  It will be popped off in the
68            child in the ebx frobbing below.  */
69         movq    %rdi,0(%rsi)
70
71         /* Do the system call.  */
72         movq    %rdx, %rdi
73         movq    %r8, %rdx
74         movq    %r9, %r8
75         movq    8(%rsp), %r10
76         movl    $__NR_clone,%eax
77
78         syscall
79
80         testq   %rax,%rax
81         jl      __syscall_error
82         jz      .Lthread_start
83
84 .Lpseudo_end:
85         ret
86
87 .Lthread_start:
88         /* Clear the frame pointer.  The ABI suggests this be done, to mark
89            the outermost frame obviously.  */
90         xorl    %ebp, %ebp
91
92 #ifdef RESET_PID
93         testq   $CLONE_THREAD, %rdi
94         jne     1f
95         testq   $CLONE_VM, %rdi
96         movl    $-1, %eax
97         jne     2f
98         movl    $__NR_getpid, %eax
99         syscall
100 2:      movl    %eax, %fs:PID
101         movl    %eax, %fs:TID
102 1:
103 #endif
104
105         /* Set up arguments for the function call.  */
106         popq    %rax            /* Function to call.  */
107         popq    %rdi            /* Argument.  */
108         call    *%rax
109         /* Call exit with return value from function call. */
110         movq    %rax, %rdi
111         movl    $__NR_exit, %eax
112         syscall
113
114 .size clone,.-clone
115 weak_alias(clone, __clone)