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 <hjl.tools@gmail.com>
Co-Authored-By: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reviewed-by: Sam James <sam@gentoo.org>
This commit is contained in:
H.J. Lu 2024-12-20 05:31:05 +08:00
parent 56cdc529fb
commit 494eb254c3
8 changed files with 203 additions and 67 deletions

View file

@ -43,13 +43,20 @@
/* Define if the compiler supports __builtin_memset. */ /* Define if the compiler supports __builtin_memset. */
#undef HAVE_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 #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__)). */ __attribute__ ((__optimize__)). */
#undef HAVE_CC_NO_STACK_PROTECTOR #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. /* The level of stack protection in use for glibc as a whole.
May be overridden on a file-by-file basis. */ May be overridden on a file-by-file basis. */
#ifndef STACK_PROTECTOR_LEVEL #ifndef STACK_PROTECTOR_LEVEL

113
configure vendored
View file

@ -6069,13 +6069,14 @@ rm -f conftest*
config_vars="$config_vars config_vars="$config_vars
have-test-clangxx = $libc_cv_test_clangxx" have-test-clangxx = $libc_cv_test_clangxx"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5
printf %s "checking for -fstack-protector... " >&6; } printf %s "checking for -fstack-protector... " >&6; }
if test ${libc_cv_ssp+y} if test ${libc_cv_ssp+y}
then : then :
printf %s "(cached) " >&6 printf %s "(cached) " >&6
else case e in #( 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 echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5 (eval $ac_try) 2>&5
ac_status=$? ac_status=$?
@ -6086,12 +6087,44 @@ then :
else case e in #( else case e in #(
e) libc_cv_ssp=no ;; e) libc_cv_ssp=no ;;
esac esac
fi fi ;;
;;
esac esac
fi fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5
printf "%s\n" "$libc_cv_ssp" >&6; } 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\n" "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5
printf %s "checking for -fstack-protector-strong... " >&6; } 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 printf "%s\n" "#define HAVE_CC_NO_STACK_PROTECTOR 1" >>confdefs.h
fi 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 if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
stack_protector="-fstack-protector" stack_protector="-fstack-protector"
@ -7713,38 +7751,77 @@ CC="$saved_CC"
config_vars="$config_vars config_vars="$config_vars
test-config-cflags-float-store = $libc_cv_test_cc_float_store" 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 \ conftest_code="
__attribute__ ((__optimize__))" >&5 void
printf %s "checking if $CC accepts -fno-tree-loop-distribute-patterns with \ __attribute__ ((__optimize__ (\"-fno-tree-loop-distribute-patterns\")))
__attribute__ ((__optimize__))... " >&6; } 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} if test ${libc_cv_cc_loop_to_function+y}
then : then :
printf %s "(cached) " >&6 printf %s "(cached) " >&6
else case e in #( else case e in #(
e) cat > conftest.c <<EOF e) if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c -Werror conftest.c -o conftest 1>&5'
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'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5 (eval $ac_try) 2>&5
ac_status=$? ac_status=$?
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; } test $ac_status = 0; }; }
then then
libc_cv_cc_loop_to_function=yes libc_cv_cc_loop_to_function=yes
fi else
rm -f conftest* ;; libc_cv_cc_loop_to_function=no
fi
;;
esac esac
fi fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_loop_to_function" >&5 { 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; } 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 if test $libc_cv_cc_loop_to_function = yes; then
printf "%s\n" "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h printf "%s\n" "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h
fi 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

View file

@ -665,11 +665,14 @@ LIBC_TRY_TEST_CXX_COMMAND([for clang++],
) )
LIBC_CONFIG_VAR([have-test-clangxx], [$libc_cv_test_clangxx]) LIBC_CONFIG_VAR([have-test-clangxx], [$libc_cv_test_clangxx])
AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl LIBC_TRY_CC_AND_TEST_CC_OPTION([for -fstack-protector],
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector], [-Werror -fstack-protector],
[libc_cv_ssp=yes], libc_cv_ssp,
[libc_cv_ssp=no]) [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 AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong], 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" no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR) AC_DEFINE(HAVE_CC_NO_STACK_PROTECTOR)
fi 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 if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
stack_protector="-fstack-protector" 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_CONFIG_VAR([test-config-cflags-float-store],
[$libc_cv_test_cc_float_store]) [$libc_cv_test_cc_float_store])
AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \ conftest_code="
__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl
cat > conftest.c <<EOF
void void
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) __attribute__ ((__optimize__ (\"-fno-tree-loop-distribute-patterns\")))
foo (void) {} foo (void) {}
EOF "
libc_cv_cc_loop_to_function=no LIBC_TRY_CC_AND_TEST_CC_COMMAND([if __attribute__ ((__optimize__("-fno-tree-loop-distribute-patterns"))) works],
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c]) [$conftest_code],
then [-c -Werror],
libc_cv_cc_loop_to_function=yes libc_cv_cc_loop_to_function,
fi [libc_cv_cc_loop_to_function=yes],
rm -f conftest*]) [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 if test $libc_cv_cc_loop_to_function = yes; then
AC_DEFINE(HAVE_CC_INHIBIT_LOOP_TO_LIBCALL) AC_DEFINE(HAVE_CC_INHIBIT_LOOP_TO_LIBCALL)
fi 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) AC_SUBST(libc_cv_cc_loop_to_function)
LIBC_TRY_CC_AND_TEST_CC_OPTION([for -Wimplicit-fallthrough], LIBC_TRY_CC_AND_TEST_CC_OPTION([for -Wimplicit-fallthrough],

67
include/libc-misc.h Normal file
View file

@ -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

View file

@ -59,6 +59,8 @@
# define IN_MODULE (-1) # define IN_MODULE (-1)
#endif #endif
#include <libc-misc.h>
#ifndef _ISOMAC #ifndef _ISOMAC
/* This is defined for the compilation of all C library code. features.h /* 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"))) #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 /* The following macros are used for PLT bypassing within libc.so
(and if needed other libraries similarly). (and if needed other libraries similarly).
First of all, you need to have the function prototyped somewhere, First of all, you need to have the function prototyped somewhere,
@ -804,16 +797,6 @@ for linking")
#define libm_ifunc_init() #define libm_ifunc_init()
#define libm_ifunc(name, expr) \ #define libm_ifunc(name, expr) \
__ifunc (name, name, expr, void, libm_ifunc_init) __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. /* These macros facilitate sharing source files with gnulib.

View file

@ -47,7 +47,7 @@ IMPL (memmove, 1)
/* Naive implementation to verify results. */ /* Naive implementation to verify results. */
char * char *
inhibit_loop_to_libcall test_cc_inhibit_loop_to_libcall
simple_memmove (char *dst, const char *src, size_t n) simple_memmove (char *dst, const char *src, size_t n)
{ {
char *ret = dst; char *ret = dst;

View file

@ -64,7 +64,7 @@ IMPL (MEMSET, 1)
/* Naive implementation to verify results. */ /* Naive implementation to verify results. */
CHAR * CHAR *
inhibit_loop_to_libcall test_cc_inhibit_loop_to_libcall
SIMPLE_MEMSET (CHAR *s, int c, size_t n) SIMPLE_MEMSET (CHAR *s, int c, size_t n)
{ {
CHAR *r = s, *end = s + n; CHAR *r = s, *end = s + n;

View file

@ -40,16 +40,7 @@ extern impl_t __start_impls[], __stop_impls[];
#undef __USE_STRING_INLINES #undef __USE_STRING_INLINES
/* We are compiled under _ISOMAC, so libc-symbols.h does not do this #include "libc-misc.h"
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 <getopt.h> #include <getopt.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>