[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