From 494eb254c37507e836b5c791a3dbd8552777ddf7 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 20 Dec 2024 05:31:05 +0800 Subject: [PATCH] Add include/libc-misc.h 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 Co-Authored-By: Adhemerval Zanella Reviewed-by: Sam James --- 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 c3e850a9c8..58f05957f4 100755 --- a/configure +++ b/configure @@ -6069,13 +6069,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=$? @@ -6086,12 +6087,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; } @@ -6148,6 +6181,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" @@ -7713,38 +7751,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 <&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 <&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 aa0ec5d7ff..8f75b319a3 100644 --- a/configure.ac +++ b/configure.ac @@ -665,11 +665,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], @@ -689,6 +692,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" @@ -1506,22 +1513,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 <. */ + +#ifndef _INCLUDE_MISC_H +#define _INCLUDE_MISC_H + +#include + +/* 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 + #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 #include #include