[roland/nptl-sh] SH: Consolidate NPTL/non versions of vfork

Message ID 20140529230926.133C22C3C21@topped-with-meat.com
State Committed
Headers

Commit Message

Roland McGrath May 29, 2014, 11:09 p.m. UTC
  I haven't tried to compile this or anything.  It should result in no
changes to the object code.  The only change should be in libpthread.so's
symbol table, where the {__,}vfork@@GLIBC_x.y symbols become just
@GLIBC_x.y.  It might be ideal to avoid the copy of the vfork code in
libpthread, as I've done for other machines.  That would need the
__libc_vfork alias added to vfork.S and then either an assembly
implementation of a tail call to the __libc_vfork PLT entry or testimony
that a C tail call will definitely get compiled into a proper tail call.
I'll leave that further cleanup to Kaz.


Thanks,
Roland


2014-05-29  Roland McGrath  <roland@hack.frob.com>

	* nptl/sysdeps/unix/sysv/linux/sh/vfork.S: Moved ...
	* sysdeps/unix/sysv/linux/sh/vfork.S: ... here.
	* sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
	* nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S: File removed.
  

Comments

Kaz Kojima May 30, 2014, 4:47 a.m. UTC | #1
Roland McGrath <roland@hack.frob.com> wrote:
> I haven't tried to compile this or anything.  It should result in no
> changes to the object code.  The only change should be in libpthread.so's
> symbol table, where the {__,}vfork@@GLIBC_x.y symbols become just
> @GLIBC_x.y.  It might be ideal to avoid the copy of the vfork code in
> libpthread, as I've done for other machines.  That would need the
> __libc_vfork alias added to vfork.S and then either an assembly
> implementation of a tail call to the __libc_vfork PLT entry or testimony
> that a C tail call will definitely get compiled into a proper tail call.
> I'll leave that further cleanup to Kaz.
> 
> 
> Thanks,
> Roland
> 
> 
> 2014-05-29  Roland McGrath  <roland@hack.frob.com>
> 
> 	* nptl/sysdeps/unix/sysv/linux/sh/vfork.S: Moved ...
> 	* sysdeps/unix/sysv/linux/sh/vfork.S: ... here.
> 	* sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
> 	* nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S: File removed.

vfork.S part works as expected in my environment.

> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sh/pt-vfork.S
[snip]
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_20)
> +# include <vfork.S>
> +
> +compat_symbol (__vfork, __vfork, GLIBC_2_0)
> +compat_symbol (vfork, vfork, GLIBC_2_0)
> +#endif

I thought that pt-vfork.S is for libpthread.so and
it would be

#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
# include <vfork.S>

compat_symbol (libpthread, __vfork, __vfork, GLIBC_2_0)
compat_symbol (libpthread, vfork, vfork, GLIBC_2_0)
#endif

Am I missing something here?

Regards,
	kaz
  
Roland McGrath May 30, 2014, 4:19 p.m. UTC | #2
> vfork.S part works as expected in my environment.

Great.

> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/sh/pt-vfork.S
> [snip]
> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_20)
> > +# include <vfork.S>
> > +
> > +compat_symbol (__vfork, __vfork, GLIBC_2_0)
> > +compat_symbol (vfork, vfork, GLIBC_2_0)
> > +#endif
> 
> I thought that pt-vfork.S is for libpthread.so and
> it would be
> 
> #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
> # include <vfork.S>
> 
> compat_symbol (libpthread, __vfork, __vfork, GLIBC_2_0)
> compat_symbol (libpthread, vfork, vfork, GLIBC_2_0)
> #endif
> 
> Am I missing something here?

Nope.  You are correct.  It's easy to forget these little details when you
don't bother trying to compile it. ;-)

I've made that fix on the branch.  Please let me know if it works now.
(Or feel free to just commit it yourself if you prefer.)


Thanks,
Roland
  
Richard Henderson May 30, 2014, 5:52 p.m. UTC | #3
On 05/30/2014 09:19 AM, Roland McGrath wrote:
>> vfork.S part works as expected in my environment.
> Great.
> 
>>> > > --- /dev/null
>>> > > +++ b/sysdeps/unix/sysv/linux/sh/pt-vfork.S
>> > [snip]
>>> > > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_20)
>>> > > +# include <vfork.S>
>>> > > +
>>> > > +compat_symbol (__vfork, __vfork, GLIBC_2_0)
>>> > > +compat_symbol (vfork, vfork, GLIBC_2_0)
>>> > > +#endif
>> > 
>> > I thought that pt-vfork.S is for libpthread.so and
>> > it would be
>> > 
>> > #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
>> > # include <vfork.S>
>> > 
>> > compat_symbol (libpthread, __vfork, __vfork, GLIBC_2_0)
>> > compat_symbol (libpthread, vfork, vfork, GLIBC_2_0)
>> > #endif
>> > 
>> > Am I missing something here?
> Nope.  You are correct.  It's easy to forget these little details when you
> don't bother trying to compile it. ;-)
> 
> I've made that fix on the branch.  Please let me know if it works now.
> (Or feel free to just commit it yourself if you prefer.)

You should be able to reuse the Alpha pt-vfork.S to get the compat symbols
correct.  C.f. Alpha's vfork.S for which symbols to define there.


r~
  
Roland McGrath May 30, 2014, 6:40 p.m. UTC | #4
> You should be able to reuse the Alpha pt-vfork.S to get the compat symbols
> correct.  C.f. Alpha's vfork.S for which symbols to define there.

Thanks.  I've updated the roland/nptl-sh branch to do this.
  
Richard Henderson May 30, 2014, 7:03 p.m. UTC | #5
On 05/30/2014 11:40 AM, Roland McGrath wrote:
>> You should be able to reuse the Alpha pt-vfork.S to get the compat symbols
>> correct.  C.f. Alpha's vfork.S for which symbols to define there.
> 
> Thanks.  I've updated the roland/nptl-sh branch to do this.
> 

You missed the bit about the symbols:

The function should be defined as __libc_vfork, and the vfork, __vfork, and
libc_hidden_def should only be defined if !NOT_IN_libc.


r~
  
Roland McGrath May 30, 2014, 8:02 p.m. UTC | #6
> You missed the bit about the symbols:
> 
> The function should be defined as __libc_vfork, and the vfork, __vfork, and
> libc_hidden_def should only be defined if !NOT_IN_libc.

I see.  I've updated the branch.

Thanks,
Roland
  

Patch

--- a/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S
+++ /dev/null
@@ -1,65 +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>
-#define _ERRNO_H	1
-#include <bits/errno.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
-   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
-   and the process ID of the new process to the old process.  */
-
-ENTRY (__vfork)
-	/* Save the PID value.  */
-	stc	gbr, r2
-	mov.w	.L2, r0
-	mov.l	@(r0,r2), r4
-	neg	r4, r1
-	mov.l	r1, @(r0,r2)
-
-	mov.w	.L1, r3
-	trapa	#0x10
-	mov     r0, r1
-
-	/* Restore the old PID value in the parent.  */
-	tst	r0, r0
-	bt/s	2f
-	 stc	gbr, r2
-	mov.w	.L2, r0
-	mov.l	r4, @(r0,r2)
-	mov	r1, r0
-2:
-	mov	#-12, r2
-	shad	r2, r1
-	not	r1, r1			// r1=0 means r0 = -1 to -4095
-	tst	r1, r1			// i.e. error in linux
-	bf	.Lpseudo_end
-	SYSCALL_ERROR_HANDLER
-.Lpseudo_end:
-	rts
-	 nop
-.L1:
-	.word	__NR_vfork
-.L2:
-	.word	PID - TLS_PRE_TCB_SIZE
-
-PSEUDO_END (__vfork)
-libc_hidden_def (__vfork)
-
-weak_alias (__vfork, vfork)
--- a/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
+++ /dev/null
@@ -1,70 +0,0 @@ 
-/* Copyright (C) 2004-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>
-#define _ERRNO_H	1
-#include <bits/errno.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
-   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
-   and the process ID of the new process to the old process.  */
-
-ENTRY (__vfork)
-	/* Save the PID value.  */
-	stc	gbr, r2
-	mov.w	.L2, r0
-	mov.l	@(r0,r2), r4
-	neg	r4, r1
-	tst	r1, r1
-	bf	1f
-	mov	#1, r1
-	rotr	r1
-1:
-	mov.l	r1, @(r0,r2)
-
-	mov.w	.L1, r3
-	trapa	#0x10
-	mov     r0, r1
-
-	/* Restore the old PID value in the parent.  */
-	tst	r0, r0
-	bt.s	2f
-	 stc	gbr, r2
-	mov.w	.L2, r0
-	mov.l	r4, @(r0,r2)
-	mov	r1, r0
-2:
-	mov	#-12, r2
-	shad	r2, r1
-	not	r1, r1			// r1=0 means r0 = -1 to -4095
-	tst	r1, r1			// i.e. error in linux
-	bf	.Lpseudo_end
-	SYSCALL_ERROR_HANDLER
-.Lpseudo_end:
-	rts
-	 nop
-.L1:
-	.word	__NR_vfork
-.L2:
-	.word	PID - TLS_PRE_TCB_SIZE
-	.align	2
-PSEUDO_END (__vfork)
-libc_hidden_def (__vfork)
-
-weak_alias (__vfork, vfork)
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/pt-vfork.S
@@ -0,0 +1,28 @@ 
+/* libpthread ABI compatibility entry point for vfork.  SH version.
+   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 has its own copy of vfork only for ABI compatibility.  */
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_20)
+# include <vfork.S>
+
+compat_symbol (__vfork, __vfork, GLIBC_2_0)
+compat_symbol (vfork, vfork, GLIBC_2_0)
+#endif
--- a/sysdeps/unix/sysv/linux/sh/vfork.S
+++ b/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 1999-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2004-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
@@ -18,6 +18,7 @@ 
 #include <sysdep.h>
 #define _ERRNO_H	1
 #include <bits/errno.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
@@ -25,45 +26,44 @@ 
    and the process ID of the new process to the old process.  */
 
 ENTRY (__vfork)
-
-#ifdef __NR_vfork
-	mov.w	.L3, r3
-	trapa	#0x10
-	mov     r0, r1
-	mov	#-12, r2
-	shad	r2, r1
-	not	r1, r1			// r1=0 means r0 = -1 to -4095
-	tst	r1, r1			// i.e. error in linux
+	/* Save the PID value.  */
+	stc	gbr, r2
+	mov.w	.L2, r0
+	mov.l	@(r0,r2), r4
+	neg	r4, r1
+	tst	r1, r1
 	bf	1f
-	mov.w	.L1, r1
-	cmp/eq	r1, r0
-	bt	2f
-	bra	.Lsyscall_error
-	 nop
-.L1:
-	.word	-ENOSYS
-.L3:	.word	__NR_vfork
+	mov	#1, r1
+	rotr	r1
 1:
-	rts
-	 nop
-2:
-#endif
+	mov.l	r1, @(r0,r2)
 
-	/* If we don't have vfork, fork is close enough.  */
-	mov	#+__NR_fork, r3
+	mov.w	.L1, r3
 	trapa	#0x10
 	mov     r0, r1
+
+	/* Restore the old PID value in the parent.  */
+	tst	r0, r0
+	bt.s	2f
+	 stc	gbr, r2
+	mov.w	.L2, r0
+	mov.l	r4, @(r0,r2)
+	mov	r1, r0
+2:
 	mov	#-12, r2
 	shad	r2, r1
 	not	r1, r1			// r1=0 means r0 = -1 to -4095
 	tst	r1, r1			// i.e. error in linux
 	bf	.Lpseudo_end
-.Lsyscall_error:
 	SYSCALL_ERROR_HANDLER
 .Lpseudo_end:
 	rts
 	 nop
-
+.L1:
+	.word	__NR_vfork
+.L2:
+	.word	PID - TLS_PRE_TCB_SIZE
+	.align	2
 PSEUDO_END (__vfork)
 libc_hidden_def (__vfork)