@@ -1,5 +1,13 @@
2014-05-23 Richard Henderson <rth@twiddle.net>
+ * sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove vfork.
+ * sysdeps/unix/sysv/linux/alpha/nptl/vfork.S: Move file ...
+ * sysdeps/unix/sysv/linux/alpha/vfork.S: ... here. Restore PID
+ before exiting on error.
+ (__libc_vfork): New strong alias.
+ * sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S: Remove file.
+ * sysdeps/unix/sysv/linux/alpha/pt-vfork.S: New file.
+
* sysdeps/unix/sysv/linux/alpha/clone.S: Deconditionalize the code
that was previously under [RESET_PID].
* sysdeps/unix/sysv/linux/alpha/nptl/clone.S: File removed.
deleted file mode 100644
@@ -1,42 +0,0 @@
-/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library. If not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#include <tcb-offsets.h>
-
-#undef PSEUDO_PREPARE_ARGS
-#define PSEUDO_PREPARE_ARGS \
- /* Load the current cached pid value across the vfork. */ \
- rduniq; \
- ldl a2, PID_OFFSET(v0); \
- mov v0, a1; \
- /* Write back its negation, to indicate that the pid value is \
- uninitialized in the child, and in the window between \
- here and the point at which we restore the value. */ \
- negl a2, t0; \
- stl t0, PID_OFFSET(v0);
-
-PSEUDO (__vfork, vfork, 0)
-
- /* If we're back in the parent, restore the saved pid. */
- beq v0, 1f
- stl a2, PID_OFFSET(a1)
-1: ret
-
-PSEUDO_END (__vfork)
-
-weak_alias (__vfork, vfork)
new file mode 100644
@@ -0,0 +1,34 @@
+/* vfork ABI-compatibility entry points for libpthread.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <shlib-compat.h>
+
+/* libpthread used to have its own vfork implementation that differed
+ from libc's only in having a pointless micro-optimization. There
+ is no longer any use to having a separate copy in libpthread, but
+ the historical ABI requires it. For static linking, there is no
+ need to provide anything here--the libc version will be linked in.
+ For shared library ABI compatibility, there must be __vfork and
+ vfork symbols in libpthread.so. */
+
+#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
+ || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))
+
+#include <vfork.S>
+
+#endif
@@ -14,7 +14,6 @@ semget - semget i:iii __semget semget
oldsemctl EXTRA semctl i:iiii __old_semctl semctl@GLIBC_2.0
sigstack - sigstack 2 sigstack
-vfork - vfork 0 __vfork vfork
getpriority - getpriority i:ii __getpriority getpriority
similarity index 56%
rename from sysdeps/unix/sysv/linux/alpha/nptl/vfork.S
rename to sysdeps/unix/sysv/linux/alpha/vfork.S
@@ -18,28 +18,40 @@
#include <sysdep.h>
#include <tcb-offsets.h>
-#undef PSEUDO_PREPARE_ARGS
-#define PSEUDO_PREPARE_ARGS \
- /* Load the current cached pid value across the vfork. */ \
- rduniq; \
- ldl a2, PID_OFFSET(v0); \
- mov v0, a1; \
- /* If the cached value is initialized (nonzero), then write \
- back its negation, or INT_MIN, to indicate that the pid \
- value is uninitialized in the child, and in the window \
- between here and the point at which we restore the value. */ \
- ldah t0, -0x8000; \
- negl a2, t1; \
- cmovne a2, t1, t0; \
+ENTRY(__vfork)
+ PSEUDO_PROLOGUE
+
+ /* Load the thread pointer value in A1 across the vfork. */
+ rduniq
+ mov v0, a1
+
+ /* Save the TCB-cached PID away in A2, and then negate the TCB
+ field. But if it's zero, set it to 0x80000000 instead. See
+ raise.c for the logic that relies on this value. */
+ ldl a2, PID_OFFSET(v0)
+ ldah t0, -0x8000
+ negl a2, t1
+ cmovne a2, t1, t0
stl t0, PID_OFFSET(v0);
-PSEUDO (__vfork, vfork, 0)
+ lda v0, SYS_ify(vfork)
+ call_pal PAL_callsys
- /* If we're back in the parent, restore the saved pid. */
+ /* Restore the original value of the TCB cache of the PID, if we're
+ the parent. But in the child (syscall return value equals zero),
+ leave things as they are. */
beq v0, 1f
stl a2, PID_OFFSET(a1)
-1: ret
+1:
+ /* Normal error check and return. */
+ bne a3, SYSCALL_ERROR_LABEL
+ ret
PSEUDO_END (__vfork)
libc_hidden_def (__vfork)
+
weak_alias (__vfork, vfork)
+
+#if !NOT_IN_libc
+strong_alias (__vfork, __libc_vfork)
+#endif