This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch zack/wip-sibcall-macros created. glibc-2.27.9000-236-g8f275c3


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, zack/wip-sibcall-macros has been created
        at  8f275c3146a1082c8185b227ad626517a37b1840 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8f275c3146a1082c8185b227ad626517a37b1840

commit 8f275c3146a1082c8185b227ad626517a37b1840
Author: Zack Weinberg <zackw@panix.com>
Date:   Sun Mar 18 17:12:42 2018 -0400

    RFC: Introduce pt-compat-stubs and use it to replace pt-vfork.
    
    I am looking into the possibility of eliminating all of the duplicate
    function definitions from libpthread, replacing them with
    properly-tagged weak compatibility symbols that just call the
    definition in libc.  Because one of the duplicated functions is vfork,
    the calls to libc absolutely must reuse the stack frame (a "sibcall"
    in GCC internals jargon), and on several important targets, GCC does
    not implement sibcalls, or only implements them for intra-module
    calls.  But we only need to implement a single special case,
    sibcalling a function with exactly the same signature, from
    immediately after the caller's own entry point; so doing it by hand in
    assembly language is not a crazy notion.  I believe I have managed to
    turn the trick for all currently-supported targets.  This patch just
    converts the existing vfork stub, so that review can focus on the new
    sysdep.h SIBCALL macros.
    
    	* sysdeps/generic/pt-compat-stubs.S: New file.
    	* nptl/pt-vfork.c, sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
    	* sysdeps/unix/sysv/linux/m68k/pt-vfork.c
    	* sysdeps/unix/sysv/linux/tile/pt-vfork.c
    	Remove file.
    	* nptl/Makefile (libpthread-routines): Remove pt-vfork, add
    	pt-compat-stubs.
    	(libpthread-shared-only-routines): Add pt-compat-stubs.
    	* posix/vfork.c: Define __libc_vfork as well as __vfork and vfork.
    
    	* sysdeps/generic/sysdep.h (SIBCALL): New macro to perform
    	sibling calls; the generic definition errors out if used.
    	* sysdeps/aarch64/sysdep.h, sysdeps/arm/sysdep.h
    	* sysdeps/hppa/sysdep.h, sysdeps/ia64/sysdep.h
    	* sysdeps/m68k/sysdep.h, sysdeps/microblaze/sysdep.h
    	* sysdeps/nios2/sysdep.h, sysdeps/powerpc/powerpc32/sysdep.h
    	* sysdeps/powerpc/powerpc64/sysdep.h, sysdeps/s390/s390-32/sysdep.h
    	* sysdeps/s390/s390-64/sysdep.h, sysdeps/tile/sysdep.h
    	* sysdeps/unix/alpha/sysdep.h, sysdeps/unix/mips/mips32/sysdep.h
    	* sysdeps/unix/mips/mips64/n32/sysdep.h
    	* sysdeps/unix/mips/mips64/n64/sysdep.h
    	* sysdeps/unix/sysv/linux/riscv/sysdep.h
    	* sysdeps/x86/sysdep.h
    	Provide appropriate architecture-specific definitions of
    	SIBCALL and, if necessary, SIBCALL_ENTRY.

diff --git a/nptl/Makefile b/nptl/Makefile
index 94be92c..18fbdfb 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -120,9 +120,10 @@ libpthread-routines = nptl-init vars events version pt-interp \
 		      cancellation \
 		      lowlevellock \
 		      lll_timedlock_wait lll_timedwait_tid \
-		      pt-fork pt-vfork \
+		      pt-fork \
 		      $(pthread-compat-wrappers) \
 		      pt-raise pt-system \
+		      pt-compat-stubs \
 		      flockfile ftrylockfile funlockfile \
 		      sigaction \
 		      herrno res pt-allocrtsig \
@@ -146,7 +147,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
 #		      pthread_setresgid
 
 libpthread-shared-only-routines = version pt-interp pt-allocrtsig \
-				  unwind-forcedunwind
+				  pt-compat-stubs unwind-forcedunwind
 
 # Since cancellation handling is in large parts handled using exceptions
 # we have to compile some files with exception handling enabled, some
diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c
deleted file mode 100644
index 2f890d3..0000000
--- a/nptl/pt-vfork.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* vfork ABI-compatibility entry points for libpthread.
-   Copyright (C) 2014-2018 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 <unistd.h>
-#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; so we define them using IFUNC to
-   redirect to the libc function.  */
-
-/* Note! If the architecture doesn't support IFUNC, then we need an
-   alternate target-specific mechanism to implement this.  So we just
-   assume IFUNC here and require that the target override this file
-   if necessary.
-
-   If the architecture can assume all supported versions of gcc will
-   produce a tail-call to __libc_vfork, consider including the version
-   in sysdeps/unix/sysv/linux/aarch64/pt-vfork.c.  */
-
-#if !HAVE_IFUNC
-# error "must write pt-vfork for this machine or get IFUNC support"
-#endif
-
-#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
-     || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))
-
-extern __typeof (vfork) __libc_vfork;   /* Defined in libc.  */
-
-# undef INIT_ARCH
-# define INIT_ARCH()
-# define DEFINE_VFORK(name) libc_ifunc (name, &__libc_vfork)
-
-#endif
-
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
-extern __typeof(vfork) vfork_ifunc;
-DEFINE_VFORK (vfork_ifunc)
-compat_symbol (libpthread, vfork_ifunc, vfork, GLIBC_2_0);
-#endif
-
-#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
-extern __typeof(vfork) __vfork_ifunc;
-DEFINE_VFORK (__vfork_ifunc)
-compat_symbol (libpthread, __vfork_ifunc, __vfork, GLIBC_2_1_2);
-#endif
diff --git a/posix/vfork.c b/posix/vfork.c
index d4e76ad..07cfca1 100644
--- a/posix/vfork.c
+++ b/posix/vfork.c
@@ -21,10 +21,10 @@
 /* If we don't have vfork, fork is close enough.  */
 
 __pid_t
-__vfork (void)
+__libc_vfork (void)
 {
   return __fork ();
 }
+strong_alias (__libc_vfork, __vfork)
 libc_hidden_def (__vfork)
-
-weak_alias (__vfork, vfork)
+weak_alias (__libc_vfork, vfork)
diff --git a/sysdeps/aarch64/sysdep.h b/sysdeps/aarch64/sysdep.h
index 5b30709..a790e3b 100644
--- a/sysdeps/aarch64/sysdep.h
+++ b/sysdeps/aarch64/sysdep.h
@@ -151,6 +151,15 @@
 	movk	PTR_REG (R), #:abs_g0_nc:NAME;
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)					\
+  b JUMPTARGET(dest)
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
diff --git a/sysdeps/arm/sysdep.h b/sysdeps/arm/sysdep.h
index 21673fe..b3a233b 100644
--- a/sysdeps/arm/sysdep.h
+++ b/sysdeps/arm/sysdep.h
@@ -121,6 +121,15 @@
 #define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)					\
+	b	PLTJMP(dest)
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
diff --git a/sysdeps/generic/pt-compat-stubs.S b/sysdeps/generic/pt-compat-stubs.S
new file mode 100644
index 0000000..3055cfe
--- /dev/null
+++ b/sysdeps/generic/pt-compat-stubs.S
@@ -0,0 +1,68 @@
+/* Compatibility stubs for functions formerly exposed by libpthread.
+   Copyright (C) 2018 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/>.  */
+
+/* The functions defined by this file used to have two different
+   definitions, one in libc.so and one in libpthread.so.  Nowadays,
+   only the version in libc is necessary, but libpthread must continue
+   to expose these symbols for compatibility's sake.  The stubs just
+   jump to the definition in libc.
+
+   This file is written in heavily macro-ized assembly language
+   because one of the stubs that it needs to define is vfork, and the
+   implementation of vfork must not touch the stack.  Having done the
+   work to handle that, we may as well reuse the mechanism for all of
+   the stubs.  */
+
+#include <shlib-compat.h>
+#include <sysdep.h>
+
+        compat_text_section
+
+#ifndef SIBCALL_ENTRY
+# define SIBCALL_ENTRY(name) ENTRY(name)
+#endif
+
+#define define_stub(name)						      \
+  define_stub_1(__pstub_##name, __libc_##name)
+#define define_stub_1(pstub_name, libc_name)				      \
+  SIBCALL_ENTRY(pstub_name)   ASM_LINE_SEP				      \
+  SIBCALL(libc_name)  ASM_LINE_SEP					      \
+  END(pstub_name)
+
+#define compat_stub(base, sym, ver)					      \
+  compat_stub_1(base, sym, ver, __COUNTER__)
+#define compat_stub_1(base, sym, ver, tag)				      \
+  compat_stub_2(base, sym, ver, tag)
+#define compat_stub_2(base, sym, ver, tag)				      \
+  compat_stub_3(__pstub_##base, __pstub_##base##_##tag, sym, ver)
+#define compat_stub_3(base, nonce, sym, ver)				      \
+  weak_alias(base, nonce) ASM_LINE_SEP					      \
+  compat_symbol(libpthread, nonce, sym, ver)
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
+ || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
+
+        define_stub(vfork)
+# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
+        compat_stub(vfork, vfork, GLIBC_2_0)
+# endif
+# if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
+        compat_stub(vfork, __vfork, GLIBC_2_1_2)
+# endif
+
+#endif
diff --git a/sysdeps/generic/sysdep.h b/sysdeps/generic/sysdep.h
index 934d4da..59e8ec2 100644
--- a/sysdeps/generic/sysdep.h
+++ b/sysdeps/generic/sysdep.h
@@ -33,9 +33,20 @@
 # ifndef JUMPTARGET
 #  define JUMPTARGET(sym)	sym
 # endif
+
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+# ifndef SIBCALL
+#  define SIBCALL(dest)				\
+  .error "Missing definition of SIBCALL"
+# endif
 #endif
 
-/* Makros to generate eh_frame unwind information.  */
+
+/* Macros to generate eh_frame unwind information.  */
 #ifdef __ASSEMBLER__
 # define cfi_startproc			.cfi_startproc
 # define cfi_endproc			.cfi_endproc
diff --git a/sysdeps/hppa/sysdep.h b/sysdeps/hppa/sysdep.h
index 4b13922..12cfe51 100644
--- a/sysdeps/hppa/sysdep.h
+++ b/sysdeps/hppa/sysdep.h
@@ -62,6 +62,16 @@
 #define	PSEUDO_END(name)						      \
   END (name)
 
+
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+  b JUMPTARGET(dest)
+
 #undef JUMPTARGET
 #define JUMPTARGET(name)	name
 #define SYSCALL_PIC_SETUP	/* Nothing.  */
diff --git a/sysdeps/ia64/sysdep.h b/sysdeps/ia64/sysdep.h
index 6066ebd..ba0e4a5 100644
--- a/sysdeps/ia64/sysdep.h
+++ b/sysdeps/ia64/sysdep.h
@@ -59,4 +59,13 @@
 #undef END
 #define END(sym)	.endp C_SYMBOL_NAME(sym)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+  .mib; nop 0; nop 0; br.sptk.many C_SYMBOL_NAME(dest);;
+
 #endif /* ASSEMBLER */
diff --git a/sysdeps/m68k/sysdep.h b/sysdeps/m68k/sysdep.h
index 0ecb3ea..ae085ed 100644
--- a/sysdeps/m68k/sysdep.h
+++ b/sysdeps/m68k/sysdep.h
@@ -71,4 +71,13 @@
 #  define JUMPTARGET(name)	name
 # endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)							      \
+  jbra  JUMPTARGET(dest)
+
 #endif	/* __ASSEMBLER__ */
diff --git a/sysdeps/microblaze/sysdep.h b/sysdeps/microblaze/sysdep.h
index 86cd827..091986d 100644
--- a/sysdeps/microblaze/sysdep.h
+++ b/sysdeps/microblaze/sysdep.h
@@ -70,6 +70,15 @@
 # define PSEUDO_END(name)                     \
   END (name)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+  brid JUMPTARGET(dest); nop
+
 # undef JUMPTARGET
 # ifdef PIC
 #  define JUMPTARGET(name)   name##@PLTPC
diff --git a/sysdeps/nios2/sysdep.h b/sysdeps/nios2/sysdep.h
index 38ea945..97a3e2e 100644
--- a/sysdeps/nios2/sysdep.h
+++ b/sysdeps/nios2/sysdep.h
@@ -53,7 +53,7 @@
 # else
 #  define CALL_MCOUNT				\
   mov r8, ra;					\
-  call _mount;					\
+  call _mcount;					\
   mov ra, r8;					\
   ret;
 # endif
@@ -62,4 +62,25 @@
 # define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#ifdef __PIC__
+#define SIBCALL(dest)				\
+  nextpc  r2;					\
+1:						\
+  movhi	  r3, %hiadj(_gp_got - 1b);		\
+  addi	  r3, r3, %lo(_gp_got - 1b);		\
+  addi	  r2, r2, r3;				\
+  ldw	  r2, %call(dest)(r2);			\
+  jmp	  r2
+#else
+#define SIBCALL(dest)				\
+  jmpi	  dest
+#endif
+
+
 #endif	/* __ASSEMBLER__ */
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 5f1294e..da67bf0 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -90,6 +90,14 @@ GOT_LABEL:			;					      \
   cfi_endproc;								      \
   ASM_SIZE_DIRECTIVE(name)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#define SIBCALL(dest)							      \
+  b	JUMPTARGET(dest)
+
 #if !IS_IN(rtld) && !defined(__SPE__)
 # define ABORT_TRANSACTION_IMPL \
     cmpwi    2,0;		\
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index 2df1d9b..596c40a 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -359,6 +359,46 @@ LT_LABELSUFFIX(name,_name_end): ; \
 #define	PSEUDO_END_ERRVAL(name) \
   END (name)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.
+
+   The linker will not allow sibling calls through the PLT on
+   PowerPC-64, and even if it did, it wouldn't be safe, because the
+   PLT stub would clobber our caller's save slot for r2.  Instead we
+   must perform a manual indirect jump.  Even this is only safe
+   because the functions that use SIBCALL are never called from within
+   their own shared object; if they were, DEST would return to code
+   that wasn't expecting to need to restore r2.  */
+#define SIBCALL_ENTRY(name) ENTRY_TOCLESS(name)
+#undef SIBCALL
+#if _CALL_ELF != 2
+#define SIBCALL(dest)				\
+	addis	11, 2, 1f@toc@ha;		\
+	ld	11,    1f@toc@l(11);		\
+	ld	12, 0(11);			\
+	ld	 2, 8(11);			\
+	mtctr	12;				\
+	ld	11, 16(11);			\
+	bctr;					\
+	.section ".toc","aw";			\
+1:	.quad dest;				\
+	.previous
+#else
+#define SIBCALL(dest)				\
+0:	addis	12, 12, 1f-0b @ha;		\
+	addi	12, 12, 1f-0b @l;		\
+	ld	12, 0(12);			\
+	mtctr	12;				\
+	bctr;					\
+	.section ".data.rel.ro","aw",@progbits;	\
+1:	.quad dest;				\
+	.previous
+
+#endif
+
 #else /* !__ASSEMBLER__ */
 
 #if _CALL_ELF != 2
diff --git a/sysdeps/s390/s390-32/sysdep.h b/sysdeps/s390/s390-32/sysdep.h
index 7e2763f..6ba1496 100644
--- a/sysdeps/s390/s390-32/sysdep.h
+++ b/sysdeps/s390/s390-32/sysdep.h
@@ -59,6 +59,15 @@
 #define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+  jg JUMPTARGET(dest)
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
diff --git a/sysdeps/s390/s390-64/sysdep.h b/sysdeps/s390/s390-64/sysdep.h
index a573e08..67f8f09 100644
--- a/sysdeps/s390/s390-64/sysdep.h
+++ b/sysdeps/s390/s390-64/sysdep.h
@@ -57,6 +57,15 @@
 #define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+  jg JUMPTARGET(dest)
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
diff --git a/sysdeps/sh/sysdep.h b/sysdeps/sh/sysdep.h
index 37889fb..63eab89 100644
--- a/sysdeps/sh/sysdep.h
+++ b/sysdeps/sh/sysdep.h
@@ -66,6 +66,20 @@
 #define CALL_MCOUNT		/* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+	mov.l	1f, r1;				\
+	braf	r1;				\
+	nop;					\
+0:	.align 2;				\
+1:	.long	dest@PLT+(.-0b)
+
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */
diff --git a/sysdeps/sparc/sysdep.h b/sysdeps/sparc/sysdep.h
index 487852c..130d782 100644
--- a/sysdeps/sparc/sysdep.h
+++ b/sysdeps/sparc/sysdep.h
@@ -79,4 +79,13 @@ C_LABEL(name)				\
 #undef LOC
 #define LOC(name)  .L##name
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)			\
+  jmp dest
+
 #endif	/* __ASSEMBLER__ */
diff --git a/sysdeps/tile/sysdep.h b/sysdeps/tile/sysdep.h
index bb82d3c..aee9893 100644
--- a/sysdeps/tile/sysdep.h
+++ b/sysdeps/tile/sysdep.h
@@ -56,6 +56,15 @@
 #define CALL_MCOUNT             /* Do nothing.  */
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)				\
+	j	plt(dest)
+
 /* Local label name for asm code. */
 #define L(name)		.L##name
 
diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h
index 104aa8e..263117f 100644
--- a/sysdeps/unix/alpha/sysdep.h
+++ b/sysdeps/unix/alpha/sysdep.h
@@ -148,6 +148,16 @@ __LABEL(name)						\
 #undef PSEUDO_END_ERRVAL
 #define PSEUDO_END_ERRVAL(sym)  END(sym)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#define SIBCALL(dest)				\
+	ldgp	gp, 0(pv);			\
+	lda	pv, dest;			\
+	jmp	(pv), dest
+
 #define ret_ERRVAL ret
 
 #define r0	v0
diff --git a/sysdeps/unix/mips/mips32/sysdep.h b/sysdeps/unix/mips/mips32/sysdep.h
index 825d007..a45eba7 100644
--- a/sysdeps/unix/mips/mips32/sysdep.h
+++ b/sysdeps/unix/mips/mips32/sysdep.h
@@ -54,3 +54,28 @@ L(syse1):
   bne a3, zero, 99b;							      \
 L(syse1):
 #endif
+
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#ifdef __PIC__
+#define SIBCALL(dest)							      \
+	.set	nomips16;						      \
+	.set	noreorder;						      \
+	.cpload $25;							      \
+	.set	nomacro;						      \
+	lw	$25, %call16(dest)($28);				      \
+	nop;								      \
+	.reloc	1f, R_MIPS_JALR, dest;					      \
+1:	jr	$25;							      \
+	nop
+#else
+#define SIBCALL(dest)							      \
+	.set	nomips16;						      \
+	.set	noreorder;						      \
+	.set	nomacro;						      \
+	j	dest;							      \
+	nop
+#endif
diff --git a/sysdeps/unix/mips/mips64/n32/sysdep.h b/sysdeps/unix/mips/mips64/n32/sysdep.h
index 78c1eca..caae9a4 100644
--- a/sysdeps/unix/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/mips/mips64/n32/sysdep.h
@@ -61,4 +61,35 @@ L(syse1):
 L(syse1):
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#ifdef __PIC__
+/* There's no PLT on MIPS/n32, we are expected to load the address by
+   hand, but the usual gp register on MIPS ($28) is call-saved so we
+   can't use it.  Use $at ($1) instead.  */
+#define SIBCALL(dest)							      \
+  .set	nomips16;							      \
+  .set	noreorder;							      \
+  .set	nomacro;							      \
+  .set	noat;								      \
+0:	lui	$1,	%hi(%neg(%gp_rel(0b)));				      \
+	addiu	$1, $1, %lo(%neg(%gp_rel(0b)));				      \
+	addu	$1, $1, $25;						      \
+	lw	$1, %call16(dest)($1);					      \
+	nop;								      \
+	.reloc	1f, R_MIPS_JALR, dest;					      \
+1:	jr	$25;							      \
+	nop
+#else
+#define SIBCALL(dest)							      \
+  .set	nomips16;							      \
+  .set	noreorder;							      \
+  .set	nomacro;							      \
+	j	dest;							      \
+	nop
 #endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/mips/mips64/n64/sysdep.h b/sysdeps/unix/mips/mips64/n64/sysdep.h
index a559917..167f330 100644
--- a/sysdeps/unix/mips/mips64/n64/sysdep.h
+++ b/sysdeps/unix/mips/mips64/n64/sysdep.h
@@ -61,4 +61,27 @@ L(syse1):
 L(syse1):
 #endif
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#define SIBCALL(dest)							      \
+/* There's no PLT on MIPS/n64, we are expected to load the address by
+   hand, but the usual gp register on MIPS ($28) is call-saved so we
+   can't use it.  Use $at ($1) instead.  */
+#define SIBCALL(dest)							      \
+  .set	nomips16;							      \
+  .set	noreorder;							      \
+  .set	nomacro;							      \
+  .set	noat;								      \
+0:	lui	$1,	%hi(%neg(%gp_rel(0b)));				      \
+	daddiu	$1, $1, %lo(%neg(%gp_rel(0b)));				      \
+	daddu	$1, $1, $25;						      \
+	ld	$1, %call16(dest)($1);					      \
+	nop;								      \
+	.reloc	1f, R_MIPS_JALR, dest;					      \
+1:	jr	$25;							      \
+	nop
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c b/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
deleted file mode 100644
index 2b277f2..0000000
--- a/sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* vfork ABI-compatibility entry points for libpthread.
-   Copyright (C) 2014-2018 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 HAVE_IFUNC
-# include <nptl/pt-vfork.c>
-#elif (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
-       || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))
-
-/* Thankfully, on AArch64 we can rely on the compiler generating
-   a tail call here.  */
-
-extern void __libc_vfork (void);
-
-void
-vfork_compat (void)
-{
-  __libc_vfork ();
-}
-
-# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
-compat_symbol (libpthread, vfork_compat, vfork, GLIBC_2_0);
-# endif
-
-# if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
-strong_alias (vfork_compat, vfork_compat2)
-compat_symbol (libpthread, vfork_compat2, __vfork, GLIBC_2_1_2);
-# endif
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/m68k/pt-vfork.c b/sysdeps/unix/sysv/linux/m68k/pt-vfork.c
deleted file mode 100644
index 5fbc652..0000000
--- a/sysdeps/unix/sysv/linux/m68k/pt-vfork.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/aarch64/pt-vfork.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
index 5470ea3..0a2c2f8 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -107,6 +107,15 @@
 # undef ret_ERRVAL
 # define ret_ERRVAL ret
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)					\
+  tail	JUMPTARGET(dest)
+
 #endif /* __ASSEMBLER__ */
 
 /* In order to get __set_errno() definition in INLINE_SYSCALL.  */
diff --git a/sysdeps/unix/sysv/linux/tile/pt-vfork.c b/sysdeps/unix/sysv/linux/tile/pt-vfork.c
deleted file mode 100644
index 5fbc652..0000000
--- a/sysdeps/unix/sysv/linux/tile/pt-vfork.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/unix/sysv/linux/aarch64/pt-vfork.c>
diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
index afcb7cf..6baf03d 100644
--- a/sysdeps/x86/sysdep.h
+++ b/sysdeps/x86/sysdep.h
@@ -46,6 +46,15 @@
 #define ENTRY_CHK(name) ENTRY (name)
 #define END_CHK(name) END (name)
 
+/* Make a "sibling call" to DEST -- that is, transfer control to DEST
+   as-if it had been the function called by the caller of this function.
+   DEST is likely to be defined in a different shared object.  Only
+   ever used immediately after ENTRY.  Must not touch the stack at
+   all, and must preserve all argument and call-saved registers.  */
+#undef SIBCALL
+#define SIBCALL(dest)                           \
+  jmp JUMPTARGET(dest)
+
 /* Since C identifiers are not normally prefixed with an underscore
    on this system, the asm identifier `syscall_error' intrudes on the
    C name space.  Make sure we use an innocuous name.  */

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]