1/* Copyright (C) 2001-2021 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#include <sysdep.h> 19#define _ERRNO_H 1 20#include <bits/errno.h> 21#include <tcb-offsets.h> 22 23/* Clone the calling process, but without copying the whole address space. 24 The calling process is suspended until the new process exits or is 25 replaced by a call to `execve'. Return -1 for errors, 0 to the new process, 26 and the process ID of the new process to the old process. */ 27 28ENTRY (__vfork) 29 30 /* Pop the return PC value into RDI. We need a register that 31 is preserved by the syscall and that we're allowed to destroy. */ 32 popq %rdi 33 cfi_adjust_cfa_offset(-8) 34 cfi_register(%rip, %rdi) 35 36 /* Stuff the syscall number in RAX and enter into the kernel. */ 37 movl $SYS_ify (vfork), %eax 38 syscall 39 40 /* Push back the return PC. */ 41 pushq %rdi 42 cfi_adjust_cfa_offset(8) 43 44 cmpl $-4095, %eax 45 jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */ 46 47#if SHSTK_ENABLED 48 /* Check if shadow stack is in use. */ 49 xorl %esi, %esi 50 rdsspq %rsi 51 testq %rsi, %rsi 52 /* Normal return if shadow stack isn't in use. */ 53 je L(no_shstk) 54 55 testl %eax, %eax 56 /* In parent, normal return. */ 57 jnz L(no_shstk) 58 59 /* NB: In child, jump back to caller via indirect branch without 60 popping shadow stack which is shared with parent. Keep shadow 61 stack mismatched so that child returns in the vfork-calling 62 function will trigger SIGSEGV. */ 63 popq %rdi 64 cfi_adjust_cfa_offset(-8) 65 jmp *%rdi 66 67L(no_shstk): 68#endif 69 70 /* Normal return. */ 71 ret 72 73PSEUDO_END (__vfork) 74libc_hidden_def (__vfork) 75 76weak_alias (__vfork, vfork) 77strong_alias (__vfork, __libc_vfork) 78