[PATCH] x86: Set have-protected-data to no if unsupported

Sam James sam@gentoo.org
Sat Aug 23 00:28:34 GMT 2025


"H.J. Lu" <hjl.tools@gmail.com> writes:

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

have-protected-data is only used for tests, so this is OK:

Reviewed-by: Sam James <sam@gentoo.org>

>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
>  aclocal.m4               |  17 +++++
>  sysdeps/x86/Makefile     |   6 ++
>  sysdeps/x86/configure    | 131 +++++++++++++++++++++++++++++++++++++++
>  sysdeps/x86/configure.ac |  70 +++++++++++++++++++++
>  4 files changed, 224 insertions(+)
>
> diff --git a/aclocal.m4 b/aclocal.m4
> index 21801429fb..cfe9c0b538 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 9e1c8cce85..e32a430bb9 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 dff26e9b83..f495f69894 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 54960a71c9..77ba6721ec 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)


More information about the Libc-alpha mailing list