Update.
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / clone.S
bloba2c2c9a3f024c3d11ce054e66eb20f596d773989
1 /* Copyright (C) 2001 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
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.
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.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 /* clone() is even more special than fork() as it mucks with stacks
20    and invokes a function in the right context after its all over.  */
22 #include <sysdep.h>
23 #define _ERRNO_H        1
24 #include <bits/errno.h>
25 #include <asm-syntax.h>
26 #include <bp-sym.h>
27 #include <bp-asm.h>
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).
34    The parameters are passed in register from userland:
35    rdi: fn
36    rsi: child_stack
37    rdx: flags
38    rcx: arg
40    The kernel expects:
41    rax: system call number
42    rdi: flags
43    rsi: child_stack  */
46         .text
47 ENTRY (BP_SYM (__clone))
48         /* Sanity check arguments.  */
49         movq    $-EINVAL,%rax
50         testq   %rdi,%rdi               /* no NULL function pointers */
51         jz      SYSCALL_ERROR_LABEL
52         testq   %rsi,%rsi               /* no NULL stack pointers */
53         jz      SYSCALL_ERROR_LABEL
55         /* Insert the argument onto the new stack.  */
56         subq    $16,%rsi
57         movq    %rcx,8(%rsi)
59         /* Save the function pointer.  It will be popped off in the
60         child in the ebx frobbing below.  */
61         movq    %rdi,0(%rsi)
63         /* Do the system call.  */
64         movq    %rdx, %rdi
65         movq    $SYS_ify(clone),%rax
66         syscall
68         testq   %rax,%rax
69         jl      SYSCALL_ERROR_LABEL
70         jz      thread_start
72 L(pseudo_end):
73         ret
75 thread_start:
76         /* Set up arguments for the function call.  */
77         popq    %rax            /* Function to call.  */
78         popq    %rdi            /* Argument.  */
79         call    *%rax
80         /* Call exit with return value from function call. */
81         movq    %rax, %rdi
82         call    JUMPTARGET (_exit)
84 PSEUDO_END (BP_SYM (__clone))
86 weak_alias (BP_SYM (__clone), BP_SYM (clone))