]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/i386/vfork.S
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / vfork.S
CommitLineData
04277e02 1/* Copyright (C) 1999-2019 Free Software Foundation, Inc.
53ad957e
UD
2 This file is part of the GNU C Library.
3 Contributed by Andreas Schwab <schwab@gnu.org>.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
53ad957e
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
53ad957e 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
53ad957e
UD
18
19#include <sysdep.h>
20#define _ERRNO_H 1
21#include <bits/errno.h>
e2787137
RM
22#include <tcb-offsets.h>
23
3650e1d9
L
24#if SHSTK_ENABLED
25/* The shadow stack prevents us from pushing the saved return PC onto
26 the stack and returning normally. Instead we pop the shadow stack
27 and return directly. This is the safest way to return and ensures
28 any stack manipulations done by the vfork'd child doesn't cause the
29 parent to terminate when CET is enabled. */
30# undef SYSCALL_ERROR_HANDLER
31# ifdef PIC
32# define SYSCALL_ERROR_HANDLER \
330: \
34 calll .L1; \
35.L1: \
36 popl %edx; \
37.L2: \
38 addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx; \
39 movl __libc_errno@gotntpoff(%edx), %edx; \
40 negl %eax; \
41 movl %eax, %gs:(%edx); \
42 orl $-1, %eax; \
43 jmp 1b;
44# else
45# define SYSCALL_ERROR_HANDLER \
460: \
47 movl __libc_errno@indntpoff, %edx; \
48 negl %eax; \
49 movl %eax, %gs:(%edx); \
50 orl $-1, %eax; \
51 jmp 1b;
52# endif
53# undef SYSCALL_ERROR_LABEL
54# define SYSCALL_ERROR_LABEL 0f
55#endif
53ad957e
UD
56
57/* Clone the calling process, but without copying the whole address space.
58 The calling process is suspended until the new process exits or is
59 replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
60 and the process ID of the new process to the old process. */
61
62ENTRY (__vfork)
63
53ad957e
UD
64 /* Pop the return PC value into ECX. */
65 popl %ecx
fee732e5 66 cfi_adjust_cfa_offset (-4)
6c30d38f 67 cfi_register (%eip, %ecx)
53ad957e
UD
68
69 /* Stuff the syscall number in EAX and enter into the kernel. */
70 movl $SYS_ify (vfork), %eax
71 int $0x80
70829603 72
3650e1d9 73#if !SHSTK_ENABLED
70829603
UD
74 /* Jump to the return PC. Don't jump directly since this
75 disturbs the branch target cache. Instead push the return
76 address back on the stack. */
77 pushl %ecx
fee732e5 78 cfi_adjust_cfa_offset (4)
3650e1d9 79#endif
70829603 80
53ad957e 81 cmpl $-4095, %eax
70829603 82 /* Branch forward if it failed. */
70829603 83 jae SYSCALL_ERROR_LABEL
53ad957e 84
3650e1d9
L
85#if SHSTK_ENABLED
861:
87 /* Check if shadow stack is in use. */
88 xorl %edx, %edx
89 rdsspd %edx
90 testl %edx, %edx
91 /* Normal return if shadow stack isn't in use. */
92 je L(no_shstk)
93
94 /* Pop return address from shadow stack and jump back to caller
95 directly. */
96 movl $1, %edx
97 incsspd %edx
98 jmp *%ecx
99
100L(no_shstk):
101 /* Jump to the return PC. Don't jump directly since this
102 disturbs the branch target cache. Instead push the return
103 address back on the stack. */
104 pushl %ecx
105 cfi_adjust_cfa_offset (4)
106#endif
107
70829603 108 ret
53ad957e 109
53ad957e 110PSEUDO_END (__vfork)
a4baf360 111libc_hidden_def (__vfork)
53ad957e
UD
112
113weak_alias (__vfork, vfork)
e2787137 114strong_alias (__vfork, __libc_vfork)