aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2025-08-22 15:56:41 -0700
committerH.J. Lu <hjl.tools@gmail.com>2025-08-22 17:55:32 -0700
commitdd4394b2493940ce0ec4525a21be4e2e9db483d0 (patch)
treefb145f1436d0ceaf1e61668871d21178aa67ead7
parentaa4dbb2eebf7b047689f5fbad7fe58ae5434a72c (diff)
downloadglibc-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.m417
-rw-r--r--sysdeps/x86/Makefile6
-rw-r--r--sysdeps/x86/configure131
-rw-r--r--sysdeps/x86/configure.ac70
4 files changed, 224 insertions, 0 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index 2180142..cfe9c0b 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -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)