This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch zack/wip-sibcall-macros created. glibc-2.27.9000-225-gdb7252f
- From: zack at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 20 Mar 2018 01:45:50 -0000
- Subject: GNU C Library master sources branch zack/wip-sibcall-macros created. glibc-2.27.9000-225-gdb7252f
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 db7252fe6797a99631cfde366f7665e3f6fadcb9 (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=db7252fe6797a99631cfde366f7665e3f6fadcb9
commit db7252fe6797a99631cfde366f7665e3f6fadcb9
Author: Zack Weinberg <zackw@panix.com>
Date: Sun Mar 18 17:12:42 2018 -0400
WIP: Introduce pt-compat-stubs and use it to replace pt-vfork.
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/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..5e30725
--- /dev/null
+++ b/sysdeps/generic/pt-compat-stubs.S
@@ -0,0 +1,64 @@
+/* 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
+
+#define define_stub(name) \
+ define_stub_1(__pstub_##name, __libc_##name)
+#define define_stub_1(pstub_name, libc_name) \
+ ENTRY(pstub_name); \
+ SIBCALL(libc_name); \
+ 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); \
+ 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..6e01671 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(name)
+
#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..dde80bf 100644
--- a/sysdeps/ia64/sysdep.h
+++ b/sysdeps/ia64/sysdep.h
@@ -49,8 +49,7 @@
.global name; \
C_LABEL(name)
-#define LOCAL_LEAF(name) \
- .text; \
+#define LOCAL_LEAF(name) \ .text; \
.align 32; \
.proc C_SYMBOL_NAME(name); \
C_LABEL(name)
@@ -59,4 +58,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..9a3a550 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) \
+ bra.l 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..963df7e 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -90,6 +90,15 @@ 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)
+#endif
+
#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..8719894 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -359,6 +359,15 @@ 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. */
+#define SIBCALL(dest) \
+ b JUMPTARGET(dest)
+#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..36fe0ac 100644
--- a/sysdeps/sh/sysdep.h
+++ b/sysdeps/sh/sysdep.h
@@ -66,6 +66,23 @@
#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..95a1535 100644
--- a/sysdeps/unix/mips/mips64/n32/sysdep.h
+++ b/sysdeps/unix/mips/mips64/n32/sysdep.h
@@ -61,4 +61,33 @@ 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
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..8938071 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -107,6 +107,16 @@
# 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. */
+#define SIBCALL(dest) \
+ tail JUMPTARGET(dest)
+#endif
+
+
#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