]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Set have-protected-data to no if unsupported
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 22 Aug 2025 22:56:41 +0000 (15:56 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 23 Aug 2025 00:55:32 +0000 (17:55 -0700)
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>
aclocal.m4
sysdeps/x86/Makefile
sysdeps/x86/configure
sysdeps/x86/configure.ac

index 21801429fbd887732cac4b6de548aeb0a5d14f50..cfe9c0b5387ef751a20e8422297abbf4ba5eb546 100644 (file)
@@ -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],
index 9e1c8cce85cdade724f7b3249747dbb36d7d88fd..e32a430bb97f2bba715f7e8633d01765cf2917cb 100644 (file)
@@ -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)
index dff26e9b83375fa364a135282e53f829db4f1f8f..f495f69894cff98be87cc0ed0da709b5c14601d8 100644 (file)
@@ -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
 
 
index 54960a71c95edfc3053ec588b369eba4074f12fc..77ba6721ecd622661e8bdeec83c1f25561fe7c66 100644 (file)
@@ -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)