[PATCH 13/39] Add include/libc-misc.h

Sam James sam@gentoo.org
Sun Dec 22 04:27:49 GMT 2024


"H.J. Lu" <hjl.tools@gmail.com> writes:

> Add include/libc-misc.h to provide miscellaneous definitions for both
> glibc build and test:
>
> 1. Move inhibit_stack_protector to libc-misc.h and add Clang support.
> 2. Add test_inhibit_stack_protector for glibc testing.
> 3. Move inhibit_loop_to_libcall to libc-misc.h.
> 4. Add test_cc_inhibit_loop_to_libcall to handle TEST_CC != CC and
> replace inhibit_loop_to_libcall with test_cc_inhibit_loop_to_libcall
> in glibc tests.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> Co-Authored-By: Adhemerval Zanella <adhemerval.zanella@linaro.org>

Reviewed-by: Sam James <sam@gentoo.org>

> ---
>  config.h.in            |  11 +++-
>  configure              | 113 ++++++++++++++++++++++++++++++++++-------
>  configure.ac           |  43 ++++++++++------
>  include/libc-misc.h    |  67 ++++++++++++++++++++++++
>  include/libc-symbols.h |  21 +-------
>  string/test-memmove.c  |   2 +-
>  string/test-memset.c   |   2 +-
>  string/test-string.h   |  11 +---
>  8 files changed, 203 insertions(+), 67 deletions(-)
>  create mode 100644 include/libc-misc.h
>
> diff --git a/config.h.in b/config.h.in
> index 6c25c923fa..c26f98ccd6 100644
> --- a/config.h.in
> +++ b/config.h.in
> @@ -43,13 +43,20 @@
>  /* Define if the compiler supports __builtin_memset.  */
>  #undef	HAVE_BUILTIN_MEMSET
>  
> -/* Define if compiler accepts -ftree-loop-distribute-patterns.  */
> +/* Define if CC compiler accepts -ftree-loop-distribute-patterns.  */
>  #undef  HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
>  
> -/* Define if compiler accepts -fno-stack-protector in an
> +/* Define if TEST_CC compiler accepts -ftree-loop-distribute-patterns.  */
> +#undef  HAVE_TEST_CC_INHIBIT_LOOP_TO_LIBCALL
> +
> +/* Define if CC compiler accepts -fno-stack-protector in an
>     __attribute__ ((__optimize__)).  */
>  #undef	HAVE_CC_NO_STACK_PROTECTOR
>  
> +/* Define if TEST_CC compiler accepts -fno-stack-protector in an
> +   __attribute__ ((__optimize__)).  */
> +#undef	HAVE_TEST_CC_NO_STACK_PROTECTOR
> +
>  /* The level of stack protection in use for glibc as a whole.
>     May be overridden on a file-by-file basis.  */
>  #ifndef STACK_PROTECTOR_LEVEL
> diff --git a/configure b/configure
> index 32e817030c..00f9bc6fe3 100755
> --- a/configure
> +++ b/configure
> @@ -6070,13 +6070,14 @@ rm -f conftest*
>  config_vars="$config_vars
>  have-test-clangxx = $libc_cv_test_clangxx"
>  
> +
>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5
>  printf %s "checking for -fstack-protector... " >&6; }
>  if test ${libc_cv_ssp+y}
>  then :
>    printf %s "(cached) " >&6
>  else case e in #(
> -  e) if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector -xc /dev/null -S -o /dev/null'
> +  e) if { ac_try='${CC-cc} -Werror -fstack-protector -xc /dev/null -S -o /dev/null'
>    { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
>    (eval $ac_try) 2>&5
>    ac_status=$?
> @@ -6087,12 +6088,44 @@ then :
>  else case e in #(
>    e) libc_cv_ssp=no ;;
>  esac
> -fi
> - ;;
> +fi ;;
>  esac
>  fi
>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5
>  printf "%s\n" "$libc_cv_ssp" >&6; }
> +if test "$TEST_CC" = "$CC"; then
> +  libc_cv_test_ssp=$libc_cv_ssp
> +else
> +
> +saved_CC="$CC"
> +CC="$TEST_CC"
> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector in testing" >&5
> +printf %s "checking for -fstack-protector in testing... " >&6; }
> +if test ${libc_cv_test_ssp+y}
> +then :
> +  printf %s "(cached) " >&6
> +else case e in #(
> +  e) if { ac_try='${CC-cc} -Werror -fstack-protector -xc /dev/null -S -o /dev/null'
> +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> +  (eval $ac_try) 2>&5
> +  ac_status=$?
> +  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> +  test $ac_status = 0; }; }
> +then :
> +  libc_cv_test_ssp=yes
> +else case e in #(
> +  e) libc_cv_test_ssp=no ;;
> +esac
> +fi ;;
> +esac
> +fi
> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_ssp" >&5
> +printf "%s\n" "$libc_cv_test_ssp" >&6; }
> +
> +CC="$saved_CC"
> +
> +fi
> +
>  
>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5
>  printf %s "checking for -fstack-protector-strong... " >&6; }
> @@ -6149,6 +6182,11 @@ if test "$libc_cv_ssp" = yes; then
>    printf "%s\n" "#define HAVE_CC_NO_STACK_PROTECTOR 1" >>confdefs.h
>  
>  fi
> +if test "$libc_cv_test_ssp" = yes; then
> +  printf "%s\n" "#define HAVE_TEST_CC_NO_STACK_PROTECTOR 1" >>confdefs.h
> +
> +fi
> +
>  
>  if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
>    stack_protector="-fstack-protector"
> @@ -7714,38 +7752,77 @@ CC="$saved_CC"
>  config_vars="$config_vars
>  test-config-cflags-float-store = $libc_cv_test_cc_float_store"
>  
> -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-tree-loop-distribute-patterns with \
> -__attribute__ ((__optimize__))" >&5
> -printf %s "checking if $CC accepts -fno-tree-loop-distribute-patterns with \
> -__attribute__ ((__optimize__))... " >&6; }
> +conftest_code="
> +void
> +__attribute__ ((__optimize__ (\"-fno-tree-loop-distribute-patterns\")))
> +foo (void) {}
> +"
> +
> +cat > conftest.c <<EOF
> +$conftest_code
> +EOF
> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if __attribute__ ((__optimize__(\"-fno-tree-loop-distribute-patterns\"))) works" >&5
> +printf %s "checking if __attribute__ ((__optimize__(\"-fno-tree-loop-distribute-patterns\"))) works... " >&6; }
>  if test ${libc_cv_cc_loop_to_function+y}
>  then :
>    printf %s "(cached) " >&6
>  else case e in #(
> -  e) cat > conftest.c <<EOF
> -void
> -__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> -foo (void) {}
> -EOF
> -libc_cv_cc_loop_to_function=no
> -if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c'
> +  e)   if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c -Werror conftest.c -o conftest 1>&5'
>    { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
>    (eval $ac_try) 2>&5
>    ac_status=$?
>    printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
>    test $ac_status = 0; }; }
> -then
> -  libc_cv_cc_loop_to_function=yes
> -fi
> -rm -f conftest* ;;
> +  then
> +    libc_cv_cc_loop_to_function=yes
> +  else
> +    libc_cv_cc_loop_to_function=no
> +  fi
> + ;;
>  esac
>  fi
>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_loop_to_function" >&5
>  printf "%s\n" "$libc_cv_cc_loop_to_function" >&6; }
> +if test "$TEST_CC" = "$CC"; then
> +  libc_cv_test_cc_loop_to_function=$libc_cv_cc_loop_to_function
> +else
> +
> +saved_CC="$CC"
> +CC="$TEST_CC"
> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if __attribute__ ((__optimize__(\"-fno-tree-loop-distribute-patterns\"))) works in testing" >&5
> +printf %s "checking if __attribute__ ((__optimize__(\"-fno-tree-loop-distribute-patterns\"))) works in testing... " >&6; }
> +if test ${libc_cv_test_cc_loop_to_function+y}
> +then :
> +  printf %s "(cached) " >&6
> +else case e in #(
> +  e)       if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c -Werror conftest.c -o conftest 1>&5'
> +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> +  (eval $ac_try) 2>&5
> +  ac_status=$?
> +  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> +  test $ac_status = 0; }; }
> +      then
> +	libc_cv_test_cc_loop_to_function=yes
> +      else
> +	libc_cv_test_cc_loop_to_function=no
> +      fi ;;
> +esac
> +fi
> +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_cc_loop_to_function" >&5
> +printf "%s\n" "$libc_cv_test_cc_loop_to_function" >&6; }
> +
> +CC="$saved_CC"
> +
> +fi
> +rm -f conftest*
>  if test $libc_cv_cc_loop_to_function = yes; then
>    printf "%s\n" "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h
>  
>  fi
> +if test $libc_cv_test_cc_loop_to_function = yes; then
> +  printf "%s\n" "#define HAVE_TEST_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h
> +
> +fi
>  
>  
>  
> diff --git a/configure.ac b/configure.ac
> index 39c3eb94a6..79afe41d39 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -666,11 +666,14 @@ LIBC_TRY_TEST_CXX_COMMAND([for clang++],
>  )
>  LIBC_CONFIG_VAR([have-test-clangxx], [$libc_cv_test_clangxx])
>  
> -AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl
> -LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector],
> -		   [libc_cv_ssp=yes],
> -		   [libc_cv_ssp=no])
> -])
> +LIBC_TRY_CC_AND_TEST_CC_OPTION([for -fstack-protector],
> +  [-Werror -fstack-protector],
> +  libc_cv_ssp,
> +  [libc_cv_ssp=yes],
> +  [libc_cv_ssp=no],
> +  libc_cv_test_ssp,
> +  [libc_cv_test_ssp=yes],
> +  [libc_cv_test_ssp=no])
>  
>  AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl
>  LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong],
> @@ -690,6 +693,10 @@ if test "$libc_cv_ssp" = yes; then
>    no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
>    AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR)
>  fi
> +if test "$libc_cv_test_ssp" = yes; then
> +  AC_DEFINE(HAVE_TEST_CC_NO_STACK_PROTECTOR)
> +fi
> +
>  
>  if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
>    stack_protector="-fstack-protector"
> @@ -1507,22 +1514,26 @@ LIBC_TRY_TEST_CC_OPTION([for -ffloat-store],
>  LIBC_CONFIG_VAR([test-config-cflags-float-store],
>  		[$libc_cv_test_cc_float_store])
>  
> -AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \
> -__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl
> -cat > conftest.c <<EOF
> +conftest_code="
>  void
> -__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> +__attribute__ ((__optimize__ (\"-fno-tree-loop-distribute-patterns\")))
>  foo (void) {}
> -EOF
> -libc_cv_cc_loop_to_function=no
> -if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c])
> -then
> -  libc_cv_cc_loop_to_function=yes
> -fi
> -rm -f conftest*])
> +"
> +LIBC_TRY_CC_AND_TEST_CC_COMMAND([if __attribute__ ((__optimize__("-fno-tree-loop-distribute-patterns"))) works],
> +  [$conftest_code],
> +  [-c -Werror],
> +  libc_cv_cc_loop_to_function,
> +  [libc_cv_cc_loop_to_function=yes],
> +  [libc_cv_cc_loop_to_function=no],
> +  libc_cv_test_cc_loop_to_function,
> +  [libc_cv_test_cc_loop_to_function=yes],
> +  [libc_cv_test_cc_loop_to_function=no])
>  if test $libc_cv_cc_loop_to_function = yes; then
>    AC_DEFINE(HAVE_CC_INHIBIT_LOOP_TO_LIBCALL)
>  fi
> +if test $libc_cv_test_cc_loop_to_function = yes; then
> +  AC_DEFINE(HAVE_TEST_CC_INHIBIT_LOOP_TO_LIBCALL)
> +fi
>  AC_SUBST(libc_cv_cc_loop_to_function)
>  
>  LIBC_TRY_CC_AND_TEST_CC_OPTION([for -Wimplicit-fallthrough],
> diff --git a/include/libc-misc.h b/include/libc-misc.h
> new file mode 100644
> index 0000000000..23fc1c1f60
> --- /dev/null
> +++ b/include/libc-misc.h
> @@ -0,0 +1,67 @@
> +/* Miscellaneous definitions for both glibc build and test.
> +   Copyright (C) 2024 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _INCLUDE_MISC_H
> +#define _INCLUDE_MISC_H
> +
> +#include <config.h>
> +
> +/* Add the compiler optimization to inhibit loop transformation to library
> +   calls.  This is used to avoid recursive calls in memset and memmove
> +   default implementations in tests.  */
> +#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
> +# define inhibit_loop_to_libcall \
> +    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> +#else
> +# define inhibit_loop_to_libcall
> +#endif
> +
> +#ifdef HAVE_TEST_CC_INHIBIT_LOOP_TO_LIBCALL
> +# define test_cc_inhibit_loop_to_libcall \
> +    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> +#else
> +# define test_cc_inhibit_loop_to_libcall
> +#endif
> +
> +/* Used to disable stack protection in sensitive places, like ifunc
> +   resolvers and early static TLS init.  */
> +#ifdef __clang__
> +# define cc_inhibit_stack_protector \
> +    __attribute__((no_stack_protector))
> +#else
> +# define cc_inhibit_stack_protector \
> +   __attribute__ ((__optimize__ ("-fno-stack-protector")))
> +#endif
> +
> +#if IS_IN (testsuite) || IS_IN (testsuite_internal)
> +# ifdef HAVE_TEST_CC_NO_STACK_PROTECTOR
> +#  define test_inhibit_stack_protector cc_inhibit_stack_protector
> +#  define inhibit_stack_protector cc_inhibit_stack_protector
> +# else
> +#  define test_inhibit_stack_protector
> +#  define inhibit_stack_protector
> +# endif
> +#else
> +# ifdef HAVE_CC_NO_STACK_PROTECTOR
> +#  define inhibit_stack_protector cc_inhibit_stack_protector
> +# else
> +#  define test_inhibit_stack_protector
> +# endif
> +#endif
> +
> +#endif
> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
> index 4367aa6740..ff3555be9d 100644
> --- a/include/libc-symbols.h
> +++ b/include/libc-symbols.h
> @@ -59,6 +59,8 @@
>  # define IN_MODULE (-1)
>  #endif
>  
> +#include <libc-misc.h>
> +
>  #ifndef _ISOMAC
>  
>  /* This is defined for the compilation of all C library code.  features.h
> @@ -362,15 +364,6 @@ for linking")
>  #define attribute_relro __attribute__ ((section (".data.rel.ro")))
>  
>  
> -/* Used to disable stack protection in sensitive places, like ifunc
> -   resolvers and early static TLS init.  */
> -#ifdef HAVE_CC_NO_STACK_PROTECTOR
> -# define inhibit_stack_protector \
> -    __attribute__ ((__optimize__ ("-fno-stack-protector")))
> -#else
> -# define inhibit_stack_protector
> -#endif
> -
>  /* The following macros are used for PLT bypassing within libc.so
>     (and if needed other libraries similarly).
>     First of all, you need to have the function prototyped somewhere,
> @@ -804,16 +797,6 @@ for linking")
>  #define libm_ifunc_init()
>  #define libm_ifunc(name, expr)				\
>    __ifunc (name, name, expr, void, libm_ifunc_init)
> -
> -/* Add the compiler optimization to inhibit loop transformation to library
> -   calls.  This is used to avoid recursive calls in memset and memmove
> -   default implementations.  */
> -#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
> -# define inhibit_loop_to_libcall \
> -    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> -#else
> -# define inhibit_loop_to_libcall
> -#endif
>  
>  /* These macros facilitate sharing source files with gnulib.
>  
> diff --git a/string/test-memmove.c b/string/test-memmove.c
> index 8184884e31..e1b83f679d 100644
> --- a/string/test-memmove.c
> +++ b/string/test-memmove.c
> @@ -47,7 +47,7 @@ IMPL (memmove, 1)
>  
>  /* Naive implementation to verify results.  */
>  char *
> -inhibit_loop_to_libcall
> +test_cc_inhibit_loop_to_libcall
>  simple_memmove (char *dst, const char *src, size_t n)
>  {
>    char *ret = dst;
> diff --git a/string/test-memset.c b/string/test-memset.c
> index b49a2b6c35..f155d76aca 100644
> --- a/string/test-memset.c
> +++ b/string/test-memset.c
> @@ -64,7 +64,7 @@ IMPL (MEMSET, 1)
>  
>  /* Naive implementation to verify results.  */
>  CHAR *
> -inhibit_loop_to_libcall
> +test_cc_inhibit_loop_to_libcall
>  SIMPLE_MEMSET (CHAR *s, int c, size_t n)
>  {
>    CHAR *r = s, *end = s + n;
> diff --git a/string/test-string.h b/string/test-string.h
> index da108f55fe..6375972ea8 100644
> --- a/string/test-string.h
> +++ b/string/test-string.h
> @@ -40,16 +40,7 @@ extern impl_t __start_impls[], __stop_impls[];
>  
>  #undef __USE_STRING_INLINES
>  
> -/* We are compiled under _ISOMAC, so libc-symbols.h does not do this
> -   for us.  */
> -#include "config.h"
> -#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
> -# define inhibit_loop_to_libcall \
> -    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
> -#else
> -# define inhibit_loop_to_libcall
> -#endif
> -
> +#include "libc-misc.h"
>  #include <getopt.h>
>  #include <stdint.h>
>  #include <stdio.h>


More information about the Libc-alpha mailing list