[PATCH] aarch64: make GCS configure checks aarch64-only
Yury Khrustalev
yury.khrustalev@arm.com
Mon Nov 24 15:41:57 GMT 2025
We only need to enable GCS tests on AArch64 targets, however previously
the configure checks for GCS support in compiler and linker were added
for all targets which was not efficient.
To enable tests for GCS we need 4 things to be true:
- Compiler supports GCS branch protection.
- Test compiler supports GCS branch protection.
- Linker supports GCS marking of binaries.
- The CRT objects provided by the toolchain have GCS marking.
To check for the latter, we add new macro to aclocal.m4 that allows to
grep output from readelf.
We check all four and then put the result in one make variable to
simplify checks in makefiles.
---
Passes regression in AArch64. OK for trunk?
Base commit: 0f7b73f2ed
---
aclocal.m4 | 28 +++++
configure | 98 ---------------
configure.ac | 17 ---
sysdeps/aarch64/configure | 144 +++++++++++++++++++++++
sysdeps/aarch64/configure.ac | 36 ++++++
sysdeps/unix/sysv/linux/aarch64/Makefile | 4 +-
6 files changed, 210 insertions(+), 117 deletions(-)
diff --git a/aclocal.m4 b/aclocal.m4
index cfe9c0b538..5c25a71d8f 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -497,3 +497,31 @@ LIBC_CHECK_TEST_CXX(
[LIBC_TRY_CXX_OPTION([$2], [$4], [$5])])
)
])
+
+dnl Check if toolchain supports generating binaries with the required
+dnl ELF marking as checked by readelf.
+dnl LIBC_CHECK_ELF_PROPERTY([message], [pattern], [action-if-true], [action-if-false])
+AC_DEFUN([LIBC_CHECK_ELF_PROPERTY],
+[AC_MSG_CHECKING([$1])
+libc_elf_property=no
+cat > conftest.c <<EOF
+int foo (void) { return 42; }
+EOF
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared -o conftest.so conftest.c
+ 1>&AS_MESSAGE_LOG_FD])
+then
+ if AC_TRY_COMMAND([LC_ALL=C $READELF -n --wide conftest.so | grep "$2" 1>&AS_MESSAGE_LOG_FD])
+ then
+ libc_elf_property=yes
+ else
+ libc_elf_property=no
+ fi
+fi
+rm -f conftest*
+if test $libc_elf_property = yes; then
+ $3
+else
+ $4
+fi
+AC_MSG_RESULT($libc_elf_property)])
diff --git a/configure b/configure
index d2d83b40c0..09ac6ff760 100755
--- a/configure
+++ b/configure
@@ -9148,68 +9148,6 @@ printf "%s\n" "$libc_linker_feature" >&6; }
config_vars="$config_vars
load-address-ldflag = $libc_cv_load_address_ldflag"
-# Check if compilers support GCS in branch protection:
-
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -mbranch-protection=gcs" >&5
-printf %s "checking if compiler supports -mbranch-protection=gcs... " >&6; }
-if test ${libc_cv_cc_gcs+y}
-then :
- printf %s "(cached) " >&6
-else case e in #(
- e) if { ac_try='${CC-cc} -Werror -mbranch-protection=gcs -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_cc_gcs=yes
-else case e in #(
- e) libc_cv_cc_gcs=no ;;
-esac
-fi ;;
-esac
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_gcs" >&5
-printf "%s\n" "$libc_cv_cc_gcs" >&6; }
-if test "$TEST_CC" = "$CC"; then
- libc_cv_test_cc_gcs=$libc_cv_cc_gcs
-else
-
-saved_CC="$CC"
-CC="$TEST_CC"
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -mbranch-protection=gcs in testing" >&5
-printf %s "checking if compiler supports -mbranch-protection=gcs in testing... " >&6; }
-if test ${libc_cv_test_cc_gcs+y}
-then :
- printf %s "(cached) " >&6
-else case e in #(
- e) if { ac_try='${CC-cc} -Werror -mbranch-protection=gcs -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_gcs=yes
-else case e in #(
- e) libc_cv_test_cc_gcs=no ;;
-esac
-fi ;;
-esac
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_cc_gcs" >&5
-printf "%s\n" "$libc_cv_test_cc_gcs" >&6; }
-
-CC="$saved_CC"
-
-fi
-
-config_vars="$config_vars
-have-cc-gcs = $libc_cv_cc_gcs"
-config_vars="$config_vars
-have-test-cc-gcs = $libc_cv_test_cc_gcs"
-
# Check if compiler supports -fno-fp-int-builtin-inexact
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -fno-fp-int-builtin-inexact" >&5
@@ -9270,42 +9208,6 @@ fi
config_vars="$config_vars
config-cflags-no-fp-builtin-inexact = $libc_cv_cc_no_fp_builtin_inexact"
-# Check if linker supports GCS marking
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z gcs=always" >&5
-printf %s "checking for linker that supports -z gcs=always... " >&6; }
-libc_linker_feature=no
-cat > conftest.c <<EOF
-int _start (void) { return 42; }
-EOF
-if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
- -Wl,-z,gcs=always -nostdlib -nostartfiles
- -fPIC -shared -o conftest.so conftest.c
- 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
- if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,gcs=always -nostdlib \
- -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \
- | grep "warning: -z gcs=always ignored" > /dev/null 2>&1; then
- true
- else
- libc_linker_feature=yes
- fi
-fi
-rm -f conftest*
-if test $libc_linker_feature = yes; then
- libc_cv_ld_gcs=yes
-else
- libc_cv_ld_gcs=no
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
-printf "%s\n" "$libc_linker_feature" >&6; }
-config_vars="$config_vars
-have-ld-gcs = $libc_cv_ld_gcs"
-
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports --undefined-version" >&5
printf %s "checking for linker that supports --undefined-version... " >&6; }
diff --git a/configure.ac b/configure.ac
index 3b9f3688f1..73176840cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2049,18 +2049,6 @@ LIBC_LINKER_FEATURE([-Ttext-segment=$libc_cv_pde_load_address],
[libc_cv_load_address_ldflag=])
LIBC_CONFIG_VAR([load-address-ldflag], [$libc_cv_load_address_ldflag])
-# Check if compilers support GCS in branch protection:
-LIBC_TRY_CC_AND_TEST_CC_OPTION([if compiler supports -mbranch-protection=gcs],
- [-Werror -mbranch-protection=gcs],
- libc_cv_cc_gcs,
- [libc_cv_cc_gcs=yes],
- [libc_cv_cc_gcs=no],
- libc_cv_test_cc_gcs,
- [libc_cv_test_cc_gcs=yes],
- [libc_cv_test_cc_gcs=no])
-LIBC_CONFIG_VAR([have-cc-gcs], [$libc_cv_cc_gcs])
-LIBC_CONFIG_VAR([have-test-cc-gcs], [$libc_cv_test_cc_gcs])
-
# Check if compiler supports -fno-fp-int-builtin-inexact
LIBC_TRY_CC_AND_TEST_CC_OPTION([if compiler supports -fno-fp-int-builtin-inexact],
[-Werror -fno-fp-int-builtin-inexact],
@@ -2072,11 +2060,6 @@ LIBC_TRY_CC_AND_TEST_CC_OPTION([if compiler supports -fno-fp-int-builtin-inexact
[libc_cv_test_cc_no_fp_builtin_inexact=])
LIBC_CONFIG_VAR([config-cflags-no-fp-builtin-inexact], [$libc_cv_cc_no_fp_builtin_inexact])
-# Check if linker supports GCS marking
-LIBC_LINKER_FEATURE([-z gcs=always], [-Wl,-z,gcs=always],
- [libc_cv_ld_gcs=yes], [libc_cv_ld_gcs=no])
-LIBC_CONFIG_VAR([have-ld-gcs], [$libc_cv_ld_gcs])
-
LIBC_LINKER_FEATURE([--undefined-version], [-Wl,--undefined-version],
[libc_cv_ld_undefined_version=-Wl,--undefined-version],
diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
index f364e65fe7..eecdd324b2 100755
--- a/sysdeps/aarch64/configure
+++ b/sysdeps/aarch64/configure
@@ -196,3 +196,147 @@ fi
libc_cv_support_sframe=yes
+# Check if compilers support GCS in branch protection:
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -mbranch-protection=gcs" >&5
+printf %s "checking if compiler supports -mbranch-protection=gcs... " >&6; }
+if test ${libc_cv_cc_gcs+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if { ac_try='${CC-cc} -Werror -mbranch-protection=gcs -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_cc_gcs=yes
+else case e in #(
+ e) libc_cv_cc_gcs=no ;;
+esac
+fi ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_gcs" >&5
+printf "%s\n" "$libc_cv_cc_gcs" >&6; }
+if test "$TEST_CC" = "$CC"; then
+ libc_cv_test_cc_gcs=$libc_cv_cc_gcs
+else
+
+saved_CC="$CC"
+CC="$TEST_CC"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports -mbranch-protection=gcs in testing" >&5
+printf %s "checking if compiler supports -mbranch-protection=gcs in testing... " >&6; }
+if test ${libc_cv_test_cc_gcs+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) if { ac_try='${CC-cc} -Werror -mbranch-protection=gcs -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_gcs=yes
+else case e in #(
+ e) libc_cv_test_cc_gcs=no
+ ;;
+esac
+fi ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_test_cc_gcs" >&5
+printf "%s\n" "$libc_cv_test_cc_gcs" >&6; }
+
+CC="$saved_CC"
+
+fi
+
+
+# Check if linker supports GCS marking
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z gcs=always" >&5
+printf %s "checking for linker that supports -z gcs=always... " >&6; }
+libc_linker_feature=no
+cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+ -Wl,-z,gcs=always -nostdlib -nostartfiles
+ -fPIC -shared -o conftest.so conftest.c
+ 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
+ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,gcs=always -nostdlib \
+ -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \
+ | grep "warning: -z gcs=always ignored" > /dev/null 2>&1; then
+ true
+ else
+ libc_linker_feature=yes
+ fi
+fi
+rm -f conftest*
+if test $libc_linker_feature = yes; then
+ libc_cv_ld_gcs=yes
+else
+ libc_cv_ld_gcs=no
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+printf "%s\n" "$libc_linker_feature" >&6; }
+
+# Check if toolchain is enabled to support GCS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if toolchain is enabled to support GCS" >&5
+printf %s "checking if toolchain is enabled to support GCS... " >&6; }
+libc_elf_property=no
+cat > conftest.c <<EOF
+int foo (void) { return 42; }
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared -o conftest.so conftest.c
+ 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
+ if { ac_try='LC_ALL=C $READELF -n --wide conftest.so | grep "AArch64 feature: .*GCS" 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_elf_property=yes
+ else
+ libc_elf_property=no
+ fi
+fi
+rm -f conftest*
+if test $libc_elf_property = yes; then
+ libc_cv_gcs_supported=yes
+else
+ libc_cv_gcs_supported=no
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_elf_property" >&5
+printf "%s\n" "$libc_elf_property" >&6; }
+
+if test $libc_cv_cc_gcs = yes && \
+ test $libc_cv_test_cc_gcs = yes && \
+ test $libc_cv_ld_gcs = yes && \
+ test $libc_cv_gcs_supported = yes
+then
+ config_vars="$config_vars
+have-test-gcs = yes"
+else
+ config_vars="$config_vars
+have-test-gcs = no"
+fi
+
diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
index a9a1b747f1..8b01aa843d 100644
--- a/sysdeps/aarch64/configure.ac
+++ b/sysdeps/aarch64/configure.ac
@@ -33,3 +33,39 @@ if test $build_mathvec = no; then
fi
libc_cv_support_sframe=yes
+
+# Check if compilers support GCS in branch protection:
+LIBC_TRY_CC_AND_TEST_CC_OPTION(
+ [if compiler supports -mbranch-protection=gcs],
+ [-Werror -mbranch-protection=gcs],
+ libc_cv_cc_gcs,
+ [libc_cv_cc_gcs=yes],
+ [libc_cv_cc_gcs=no],
+ libc_cv_test_cc_gcs,
+ [libc_cv_test_cc_gcs=yes],
+ [libc_cv_test_cc_gcs=no]
+)
+
+# Check if linker supports GCS marking
+LIBC_LINKER_FEATURE(
+ [-z gcs=always], [-Wl,-z,gcs=always],
+ [libc_cv_ld_gcs=yes], [libc_cv_ld_gcs=no]
+)
+
+# Check if toolchain is enabled to support GCS
+LIBC_CHECK_ELF_PROPERTY(
+ [if toolchain is enabled to support GCS],
+ [AArch64 feature: .*GCS],
+ [libc_cv_gcs_supported=yes],
+ [libc_cv_gcs_supported=no]
+)
+
+if test $libc_cv_cc_gcs = yes && \
+ test $libc_cv_test_cc_gcs = yes && \
+ test $libc_cv_ld_gcs = yes && \
+ test $libc_cv_gcs_supported = yes
+then
+ LIBC_CONFIG_VAR([have-test-gcs], [yes])
+else
+ LIBC_CONFIG_VAR([have-test-gcs], [no])
+fi
diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
index e0b5b7d5b2..6741f8ec00 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Makefile
+++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
@@ -17,7 +17,7 @@ tests += \
tst-aarch64-pkey \
# tests
-ifneq (no,$(findstring no,$(have-cc-gcs) $(have-test-cc-gcs) $(have-ld-gcs)))
+ifeq (yes,$(have-test-gcs))
gcs-tests-dynamic = \
tst-gcs-disabled \
@@ -141,7 +141,7 @@ LDFLAGS-tst-gcs-noreturn = -Wl,-z,gcs=always
tst-gcs-noreturn-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_gcs=0
-endif # ifeq ($(have-test-cc-gcs),yes)
+endif # ifeq ($(have-test-gcs),yes)
endif # ifeq ($(subdir),misc)
--
2.47.3
More information about the Libc-alpha
mailing list