diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2025-08-22 15:56:41 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2025-08-22 17:55:32 -0700 |
commit | dd4394b2493940ce0ec4525a21be4e2e9db483d0 (patch) | |
tree | fb145f1436d0ceaf1e61668871d21178aa67ead7 | |
parent | aa4dbb2eebf7b047689f5fbad7fe58ae5434a72c (diff) | |
download | glibc-dd4394b2493940ce0ec4525a21be4e2e9db483d0.zip glibc-dd4394b2493940ce0ec4525a21be4e2e9db483d0.tar.gz glibc-dd4394b2493940ce0ec4525a21be4e2e9db483d0.tar.bz2 |
x86: Set have-protected-data to no if unsupported
If the building compiler enables no direct external data access by
default, access to protected data in shared libraries from executables
must be compiled with no direct external data access. If the testing
compiler doesn't support it, set have-protected-data to no to disable
the tests which requires no direct external data access.
Add LIBC_TRY_CC_COMMAND to test a building compiler option or options
with an input file.
This fixes BZ #33286.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Sam James <sam@gentoo.org>
-rw-r--r-- | aclocal.m4 | 17 | ||||
-rw-r--r-- | sysdeps/x86/Makefile | 6 | ||||
-rw-r--r-- | sysdeps/x86/configure | 131 | ||||
-rw-r--r-- | sysdeps/x86/configure.ac | 70 |
4 files changed, 224 insertions, 0 deletions
@@ -326,6 +326,23 @@ case "$prefix" in ;; esac]) +dnl Test a CC compiler option or options with an input file. +dnl LIBC_TRY_CC_COMMAND([message], [code], [options], +dnl [CC-cache-id], [CC-action-if-true], [CC-action-if-false]) +AC_DEFUN([LIBC_TRY_CC_COMMAND], +[ +cat > conftest.c <<EOF +$2 +EOF +AC_CACHE_CHECK([$1], $4, [dnl + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $3 conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD]) + then + [$5] + else + [$6] + fi]) +rm -f conftest*]) + dnl Run a test with TEST_CC. dnl LIBC_CHECK_TEST_CC([commands]) AC_DEFUN([LIBC_CHECK_TEST_CC], diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index 9e1c8cc..e32a430 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -144,6 +144,12 @@ $(objpfx)check-gnu2-tls.out: $(common-objpfx)libc.so | grep GLIBC_ABI_GNU2_TLS > $@; \ $(evaluate-test) generated += check-gnu2-tls.out + +ifneq (,$(test-cc-cflags-no-direct-extern-access)) +CFLAGS-tst-protected1a.c += $(test-cc-cflags-no-direct-extern-access) +CFLAGS-tst-protected1b.c += $(test-cc-cflags-no-direct-extern-access) +CFLAGS-vismain.c += $(test-cc-cflags-no-direct-extern-access) +endif endif ifeq ($(subdir),gmon) diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure index dff26e9..f495f69 100644 --- a/sysdeps/x86/configure +++ b/sysdeps/x86/configure @@ -213,6 +213,137 @@ CC="$saved_CC" config_vars="$config_vars have-test-cc-cflags-mfpmath-387 = $libc_cv_have_test_cc_cflags_mfpmath_387" +conftest_code=" +extern int foo; +int * +foo_p (void) +{ + return &foo; +} +" + +cat > conftest.c <<EOF +$conftest_code +EOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if no direct extern access is enabled by default" >&5 +printf %s "checking if no direct extern access is enabled by default... " >&6; } +if test ${libc_cv_cc_no_direct_extern_access+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S -O2 -fno-pic 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_cflags_no_direct_extern_access=no +if test "$base_machine" = x86_64; then + if grep -E -q "mov[lq][ ]+foo@GOTPCREL\(%rip\)," conftest; then + libc_cv_cc_no_direct_extern_access=yes + fi +elif test "$base_machine" = i386; then + if grep -E -q "movl[ ]+foo@GOT," conftest; then + libc_cv_cc_no_direct_extern_access=yes + fi +else + echo unsupported machine: $base_machine + rm -f conftest* + exit 1 +fi + + else + +echo failed to check no direct external data access +rm -f conftest* +exit 1 + + fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_no_direct_extern_access" >&5 +printf "%s\n" "$libc_cv_cc_no_direct_extern_access" >&6; } +rm -f conftest* + + + +saved_CC="$CC" +CC="$TEST_CC" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if -mno-direct-extern-access works in testing" >&5 +printf %s "checking if -mno-direct-extern-access works in testing... " >&6; } +if test ${libc_cv_test_cc_cflags_mno_direct_extern_access+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if { ac_try='${CC-cc} -Werror -mno-direct-extern-access -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_cc_cflags_mno_direct_extern_access=yes +else case e in #( + e) libc_cv_test_cc_cflags_mno_direct_extern_access=no + ;; +esac +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_cc_cflags_mno_direct_extern_access" >&5 +printf "%s\n" "$libc_cv_test_cc_cflags_mno_direct_extern_access" >&6; } + +CC="$saved_CC" + + + + + +saved_CC="$CC" +CC="$TEST_CC" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if -fno-direct-access-external-data works in testing" >&5 +printf %s "checking if -fno-direct-access-external-data works in testing... " >&6; } +if test ${libc_cv_test_cc_cflags_fno_direct_access_external_data+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if { ac_try='${CC-cc} -Werror -fno-direct-access-external-data -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_cc_cflags_fno_direct_access_external_data=yes +else case e in #( + e) libc_cv_test_cc_cflags_fno_direct_access_external_data=no + ;; +esac +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_cc_cflags_fno_direct_access_external_data" >&5 +printf "%s\n" "$libc_cv_test_cc_cflags_fno_direct_access_external_data" >&6; } + +CC="$saved_CC" + + + +if test $libc_cv_test_cc_cflags_mno_direct_extern_access = yes; then + libc_cv_test_cc_cflags_no_direct_extern_access="-mno-direct-extern-access" +elif test $libc_cv_test_cc_cflags_fno_direct_access_external_data = yes; then + libc_cv_test_cc_cflags_no_direct_extern_access="-fno-direct-access-external-data" +fi + +config_vars="$config_vars +test-cc-cflags-no-direct-extern-access = $libc_cv_test_cc_cflags_no_direct_extern_access" + +if test "${libc_cv_cc_no_direct_extern_access}${libc_cv_test_cc_cflags_no_direct_extern_access}" = yes; then + libc_cv_protected_data=no +fi + printf "%s\n" "#define SUPPORT_STATIC_PIE 1" >>confdefs.h diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac index 54960a7..77ba672 100644 --- a/sysdeps/x86/configure.ac +++ b/sysdeps/x86/configure.ac @@ -132,5 +132,75 @@ LIBC_TRY_TEST_CC_OPTION([if -mfpmath=387 works], LIBC_CONFIG_VAR(have-test-cc-cflags-mfpmath-387, $libc_cv_have_test_cc_cflags_mfpmath_387) +conftest_code=" +extern int foo; +int * +foo_p (void) +{ + return &foo; +} +" +dnl Check if CC enables no direct extern access by default. +LIBC_TRY_CC_COMMAND([if no direct extern access is enabled by default], + [$conftest_code], + [-S -O2 -fno-pic], + libc_cv_cc_no_direct_extern_access, + [ +libc_cv_cc_cflags_no_direct_extern_access=no +if test "$base_machine" = x86_64; then + if grep -E -q "mov[lq][ ]+foo@GOTPCREL\(%rip\)," conftest; then + libc_cv_cc_no_direct_extern_access=yes + fi +elif test "$base_machine" = i386; then + if grep -E -q "movl[ ]+foo@GOT," conftest; then + libc_cv_cc_no_direct_extern_access=yes + fi +else + echo unsupported machine: $base_machine + rm -f conftest* + exit 1 +fi + ], + [ +echo failed to check no direct external data access +rm -f conftest* +exit 1 +]) + +dnl Check if TEST_CC supports -mno-direct-extern-access. +LIBC_TRY_TEST_CC_OPTION([if -mno-direct-extern-access works], + [-Werror -mno-direct-extern-access], + libc_cv_test_cc_cflags_mno_direct_extern_access, + [libc_cv_test_cc_cflags_mno_direct_extern_access=yes], + [libc_cv_test_cc_cflags_mno_direct_extern_access=no] +) + +dnl Check if TEST_CC supports -fno-direct-access-external-data. +LIBC_TRY_TEST_CC_OPTION([if -fno-direct-access-external-data works], + [-Werror -fno-direct-access-external-data], + libc_cv_test_cc_cflags_fno_direct_access_external_data, + [libc_cv_test_cc_cflags_fno_direct_access_external_data=yes], + [libc_cv_test_cc_cflags_fno_direct_access_external_data=no] +) + +if test $libc_cv_test_cc_cflags_mno_direct_extern_access = yes; then + libc_cv_test_cc_cflags_no_direct_extern_access="-mno-direct-extern-access" +elif test $libc_cv_test_cc_cflags_fno_direct_access_external_data = yes; then + libc_cv_test_cc_cflags_no_direct_extern_access="-fno-direct-access-external-data" +fi + +LIBC_CONFIG_VAR(test-cc-cflags-no-direct-extern-access, + $libc_cv_test_cc_cflags_no_direct_extern_access) + +dnl If the building compiler enables no direct external data access by +dnl default, access to protected data in shared libraries from executables +dnl must be compiled with no direct external data access. If the testing +dnl compiler doesn't support it, set have-protected-data to no to disable +dnl the tests which requires no direct external data access. +dnl +if test "${libc_cv_cc_no_direct_extern_access}${libc_cv_test_cc_cflags_no_direct_extern_access}" = yes; then + libc_cv_protected_data=no +fi + dnl Static PIE is supported. AC_DEFINE(SUPPORT_STATIC_PIE) |