Fix make-syscalls.sh VDSO support for GCC 8

Message ID alpine.DEB.2.20.1709262107420.29011@digraph.polyomino.org.uk
State New, archived
Headers

Commit Message

Joseph Myers Sept. 26, 2017, 9:08 p.m. UTC
  sysdeps/unix/make-syscalls.sh has support, used only by x32, for
generating IFUNCs for kernel VDSO symbols.  This support creates
IFUNCs by setting symbol types manually, which is bad for debug info
and does not work with current GCC mainline because it results in
errors from the checks on types of function aliases.

This patch fixes it to use the common __ifunc macro, which uses the
ifunc attribute when available and so works with GCC mainline.  Note
however that the original error resulted from an indirect inclusion of
a header declaring __gettimeofday from the generated sources, and
using __ifunc now relies on such an indirect inclusion remaining as it
means use of __typeof to determine the correct types.  If glibc's
headers change in such a way as to remove that indirect inclusion, it
will become necessary to change the syscalls.list syntax for VDSO
syscalls so the name of the header to include can be specified.

Tested (compilation only) with build-many-glibcs.py that this fixes
the build for x32 with GCC mainline.

2017-09-26  Joseph Myers  <joseph@codesourcery.com>

	* sysdeps/unix/make-syscalls.sh: Use __ifunc to define symbols
	using VDSO.
  

Comments

Carlos O'Donell Sept. 26, 2017, 9:13 p.m. UTC | #1
On 09/26/2017 03:08 PM, Joseph Myers wrote:
> sysdeps/unix/make-syscalls.sh has support, used only by x32, for
> generating IFUNCs for kernel VDSO symbols.  This support creates
> IFUNCs by setting symbol types manually, which is bad for debug info
> and does not work with current GCC mainline because it results in
> errors from the checks on types of function aliases.
> 
> This patch fixes it to use the common __ifunc macro, which uses the
> ifunc attribute when available and so works with GCC mainline.  Note
> however that the original error resulted from an indirect inclusion of
> a header declaring __gettimeofday from the generated sources, and
> using __ifunc now relies on such an indirect inclusion remaining as it
> means use of __typeof to determine the correct types.  If glibc's
> headers change in such a way as to remove that indirect inclusion, it
> will become necessary to change the syscalls.list syntax for VDSO
> syscalls so the name of the header to include can be specified.
> 
> Tested (compilation only) with build-many-glibcs.py that this fixes
> the build for x32 with GCC mainline.
> 
> 2017-09-26  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* sysdeps/unix/make-syscalls.sh: Use __ifunc to define symbols
> 	using VDSO.
Looks like a good solution for now.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
  
H.J. Lu Sept. 26, 2017, 9:20 p.m. UTC | #2
On 9/26/17, Joseph Myers <joseph@codesourcery.com> wrote:
> sysdeps/unix/make-syscalls.sh has support, used only by x32, for
> generating IFUNCs for kernel VDSO symbols.  This support creates
> IFUNCs by setting symbol types manually, which is bad for debug info
> and does not work with current GCC mainline because it results in
> errors from the checks on types of function aliases.
>
> This patch fixes it to use the common __ifunc macro, which uses the
> ifunc attribute when available and so works with GCC mainline.  Note
> however that the original error resulted from an indirect inclusion of
> a header declaring __gettimeofday from the generated sources, and
> using __ifunc now relies on such an indirect inclusion remaining as it
> means use of __typeof to determine the correct types.  If glibc's
> headers change in such a way as to remove that indirect inclusion, it
> will become necessary to change the syscalls.list syntax for VDSO
> syscalls so the name of the header to include can be specified.
>
> Tested (compilation only) with build-many-glibcs.py that this fixes
> the build for x32 with GCC mainline.
>
> 2017-09-26  Joseph Myers  <joseph@codesourcery.com>
>
> 	* sysdeps/unix/make-syscalls.sh: Use __ifunc to define symbols
> 	using VDSO.
>
> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
> index 042cfac..874ad69 100644
> --- a/sysdeps/unix/make-syscalls.sh
> +++ b/sysdeps/unix/make-syscalls.sh
> @@ -280,16 +280,14 @@ while read file srcfile caller syscall args strong
> weak; do
>  \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os):
> \\
>  		\$(..)sysdeps/unix/make-syscalls.sh
>  	\$(make-target-directory)
> -	(echo '#include <dl-vdso.h>'; \\
> -	 echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
> -	 echo 'void *'; \\
> -	 echo 'inhibit_stack_protector'; \\
> -	 echo '${strong}_ifunc (void)'; \\
> -	 echo '{'; \\
> -	 echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
> -	 echo '  return _dl_vdso_vsym ("${vdso_symbol}", &symver);'; \\
> -	 echo '}'; \\
> -	 echo 'asm (".type ${strong}, %gnu_indirect_function");'; \\
> +	(echo '#define ${strong} __redirect_${strong}'; \\
> +	 echo '#include <dl-vdso.h>'; \\
> +	 echo '#undef ${strong}'; \\
> +	 echo '#define vdso_ifunc_init() \\'; \\
> +	 echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver})'; \\
> +	 echo '__ifunc (__redirect_${strong}, ${strong},'; \\
> +	 echo '         _dl_vdso_vsym ("${vdso_symbol}", &symver), void,'; \\
> +	 echo '         vdso_ifunc_init)'; \\
>  EOF
>      # This is doing "hidden_def (${strong})", but the compiler
>      # doesn't know that we've defined ${strong} in the same file, so
>

That is OK.

Thanks.
  

Patch

diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
index 042cfac..874ad69 100644
--- a/sysdeps/unix/make-syscalls.sh
+++ b/sysdeps/unix/make-syscalls.sh
@@ -280,16 +280,14 @@  while read file srcfile caller syscall args strong weak; do
 \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
 		\$(..)sysdeps/unix/make-syscalls.sh
 	\$(make-target-directory)
-	(echo '#include <dl-vdso.h>'; \\
-	 echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
-	 echo 'void *'; \\
-	 echo 'inhibit_stack_protector'; \\
-	 echo '${strong}_ifunc (void)'; \\
-	 echo '{'; \\
-	 echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
-	 echo '  return _dl_vdso_vsym ("${vdso_symbol}", &symver);'; \\
-	 echo '}'; \\
-	 echo 'asm (".type ${strong}, %gnu_indirect_function");'; \\
+	(echo '#define ${strong} __redirect_${strong}'; \\
+	 echo '#include <dl-vdso.h>'; \\
+	 echo '#undef ${strong}'; \\
+	 echo '#define vdso_ifunc_init() \\'; \\
+	 echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver})'; \\
+	 echo '__ifunc (__redirect_${strong}, ${strong},'; \\
+	 echo '         _dl_vdso_vsym ("${vdso_symbol}", &symver), void,'; \\
+	 echo '         vdso_ifunc_init)'; \\
 EOF
     # This is doing "hidden_def (${strong})", but the compiler
     # doesn't know that we've defined ${strong} in the same file, so