1/* Copyright (C) 2001-2022 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 <https://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 <sysdep.h> 22#define _ERRNO_H 1 23#include <bits/errno.h> 24#include <asm-syntax.h> 25 26/* The userland implementation is: 27 int clone (int (*fn)(void *arg), void *child_stack, int flags, 28 void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid); 29 the kernel entry is: 30 int clone (long flags, void *child_stack, pid_t *parent_tid, 31 pid_t *child_tid, void *tls); 32 33 The parameters are passed in register and on the stack from userland: 34 rdi: fn 35 rsi: child_stack 36 rdx: flags 37 rcx: arg 38 r8: TID field in parent 39 r9: thread pointer 40%rsp+8: TID field in child 41 42 The kernel expects: 43 rax: system call number 44 rdi: flags 45 rsi: child_stack 46 rdx: TID field in parent 47 r10: TID field in child 48 r8: thread pointer */ 49 50 51 .text 52ENTRY (__clone) 53 /* Sanity check arguments. */ 54 movq $-EINVAL,%rax 55 testq %rdi,%rdi /* no NULL function pointers */ 56 jz SYSCALL_ERROR_LABEL 57 58 /* Align stack to 16 bytes per the x86-64 psABI. */ 59 andq $-16, %rsi 60 jz SYSCALL_ERROR_LABEL /* no NULL stack pointers */ 61 62 /* Insert the argument onto the new stack. */ 63 movq %rcx,-8(%rsi) 64 65 subq $16,%rsi 66 67 /* Save the function pointer. It will be popped off in the 68 child. */ 69 movq %rdi,0(%rsi) 70 71 /* Do the system call. */ 72 movq %rdx, %rdi 73 movq %r8, %rdx 74 movq %r9, %r8 75 mov 8(%rsp), %R10_LP 76 movl $SYS_ify(clone),%eax 77 78 /* End FDE now, because in the child the unwind info will be 79 wrong. */ 80 cfi_endproc; 81 syscall 82 83 testq %rax,%rax 84 jl SYSCALL_ERROR_LABEL 85 jz L(thread_start) 86 87 ret 88 89L(thread_start): 90 cfi_startproc; 91 /* Clearing frame pointer is insufficient, use CFI. */ 92 cfi_undefined (rip); 93 /* Clear the frame pointer. The ABI suggests this be done, to mark 94 the outermost frame obviously. */ 95 xorl %ebp, %ebp 96 97 /* Set up arguments for the function call. */ 98 popq %rax /* Function to call. */ 99 popq %rdi /* Argument. */ 100 call *%rax 101 /* Call exit with return value from function call. */ 102 movq %rax, %rdi 103 movl $SYS_ify(exit), %eax 104 syscall 105 cfi_endproc; 106 107 cfi_startproc; 108PSEUDO_END (__clone) 109 110libc_hidden_def (__clone) 111weak_alias (__clone, clone) 112