summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2014-05-26 11:41:28 -0500
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2014-05-26 11:41:28 -0500
commit3d1024e8d159ec5f0f3899c02af5473f5b0ec49c (patch)
tree5d25753af4e67b172b26c741eda7881e839c3774 /sysdeps/unix/sysv
parentfdfd175d46ac6a810ebdeb2a2936e6d7d13995ab (diff)
downloadglibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.tar.gz
glibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.tar.xz
glibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.zip
PowerPC: Consolidate NPTL/non versions of vfork
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S31
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S28
2 files changed, 59 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
index 7a1e8422ad..8a8433617f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
@@ -19,6 +19,7 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 #include <kernel-features.h>
+#include <tcb-offsets.h>
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -26,9 +27,39 @@
    and the process ID of the new process to the old process.  */
 
 ENTRY (__vfork)
+
+	/* Load the TCB-cached PID value and negates it. If It it is zero
+	   sets it to 0x800000.  And then sets its value again on TCB field.
+	   See raise.c for the logic that relies on this value.  */
+
+	lwz	r0,PID(r2)
+	cmpwi	cr0,r0,0
+	neg	r0,r0
+	bne-	cr0,1f
+	lis	r0,0x8000
+1:	stw	r0,PID(r2)
+
 	DO_CALL (SYS_ify (vfork))
+
+	cmpwi	cr1,r3,0
+	beqlr-	1
+
+	/* 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.  */
+	lwz	r0,PID(r2)
+	/* Cannot use clrlwi. here, because cr0 needs to be preserved
+	   until PSEUDO_RET.  */
+	clrlwi	r4,r0,1
+	cmpwi	cr1,r4,0
+	beq-	cr1,1f
+	neg	r4,r0
+1:	stw	r4,PID(r2)
+
 	PSEUDO_RET
+
 PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)
 
 weak_alias (__vfork, vfork)
+strong_alias (__vfork, __libc_vfork)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
index ebffc4c5af..72e6da85a1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
@@ -19,6 +19,7 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 #include <kernel-features.h>
+#include <tcb-offsets.h>
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -27,9 +28,36 @@
 
 ENTRY (__vfork)
 	CALL_MCOUNT 0
+
+	/* Load the TCB-cached PID value and negates it. If It it is zero
+	   sets it to 0x800000.  And then sets its value again on TCB field.
+	   See raise.c for the logic that relies on this value.  */
+	lwz	r0,PID(r13)
+	cmpwi	cr0,r0,0
+	neg	r0,r0
+	bne-	cr0,1f
+	lis	r0,0x8000
+1:	stw	r0,PID(r13)
+
 	DO_CALL (SYS_ify (vfork))
+
+	cmpwi	cr1,r3,0
+	beqlr-	1
+
+	/* 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.  */
+	lwz	r0,PID(r13)
+	clrlwi	r4,r0,1
+	cmpwi	cr1,r4,0
+	beq-	cr1,1f
+	neg	r4,r0
+1:	stw	r4,PID(r13)
+
 	PSEUDO_RET
+
 PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)
 
 weak_alias (__vfork, vfork)
+strong_alias (__vfork, __libc_vfork)