[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