about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S42
-rw-r--r--sysdeps/unix/sysv/linux/alpha/pt-vfork.S34
-rw-r--r--sysdeps/unix/sysv/linux/alpha/syscalls.list1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/vfork.S (renamed from sysdeps/unix/sysv/linux/alpha/nptl/vfork.S)44
5 files changed, 70 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 83b35992b8..faee2f5273 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S
deleted file mode 100644
index 769826e918..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S
+++ /dev/null
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/pt-vfork.S b/sysdeps/unix/sysv/linux/alpha/pt-vfork.S
new file mode 100644
index 0000000000..1d137365b2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/pt-vfork.S
@@ -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
diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
index 319ca90465..cad1fc362e 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
+++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -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
 
diff --git a/sysdeps/unix/sysv/linux/alpha/nptl/vfork.S b/sysdeps/unix/sysv/linux/alpha/vfork.S
index 083b341e3a..0507d3523e 100644
--- a/sysdeps/unix/sysv/linux/alpha/nptl/vfork.S
+++ b/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