diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2014-05-26 11:41:28 -0500 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2014-05-26 11:41:28 -0500 |
commit | 3d1024e8d159ec5f0f3899c02af5473f5b0ec49c (patch) | |
tree | 5d25753af4e67b172b26c741eda7881e839c3774 /sysdeps | |
parent | fdfd175d46ac6a810ebdeb2a2936e6d7d13995ab (diff) | |
download | glibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.tar.gz glibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.tar.xz glibc-3d1024e8d159ec5f0f3899c02af5473f5b0ec49c.zip |
PowerPC: Consolidate NPTL/non versions of vfork
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S | 31 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S | 28 |
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) |