[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