[v3,1/5] aarch64: Add configure check for linker support for -z gcs

Message ID 20250129094940.2643944-2-yury.khrustalev@arm.com (mailing list archive)
State Superseded
Delegated to: Adhemerval Zanella Netto
Headers
Series Add tests for Guarded Control Stack |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed

Commit Message

Yury Khrustalev Jan. 29, 2025, 9:49 a.m. UTC
  ---
 configure    | 36 ++++++++++++++++++++++++++++++++++++
 configure.ac |  5 +++++
 2 files changed, 41 insertions(+)
  

Comments

Adhemerval Zanella Netto Feb. 6, 2025, 7:34 p.m. UTC | #1
On 29/01/25 06:49, Yury Khrustalev wrote:
> ---
>  configure    | 36 ++++++++++++++++++++++++++++++++++++
>  configure.ac |  5 +++++
>  2 files changed, 41 insertions(+)
> 
> diff --git a/configure b/configure
> index eb8abd0054..19cae4aec7 100755
> --- a/configure
> +++ b/configure
> @@ -8908,6 +8908,42 @@ printf "%s\n" "$libc_linker_feature" >&6; }
>  config_vars="$config_vars
>  load-address-ldflag = $libc_cv_load_address_ldflag"
>  
> +# 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_test_gcs=yes
> +else
> +  libc_cv_test_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-test-cc-gcs = $libc_cv_test_gcs"
> +
>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5
>  printf %s "checking if we can build programs as PIE... " >&6; }
>  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> diff --git a/configure.ac b/configure.ac
> index 050bfa65e3..4c30d5a5b7 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1992,6 +1992,11 @@ 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 linker supports GCS marking
> +LIBC_LINKER_FEATURE([-z gcs=always], [-Wl,-z,gcs=always],
> +		    [libc_cv_test_gcs=yes], [libc_cv_test_gcs=no])
> +LIBC_CONFIG_VAR([have-test-cc-gcs], [$libc_cv_test_gcs])
> +

I think we might also need to check if compiler will ending using -z gcs
as well, otherwise users might still some failures if glibc itself it
not built with gcs.

For instance, with gcc 14 either with or without --enable-standard-branch-protection
(where gcs is support), but with a gcs enabled binutils (so have-test-cc-gcs is yes)
I see failures because at loading time libc.so.6 is not GCS compatible.

Maybe filtering out such failures (to check libc.so.6 it no GCS compatible), but it
also means that GCS won't be usable anyway.

>  AC_MSG_CHECKING(if we can build programs as PIE)
>  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED
>  # error PIE is not supported
  
Adhemerval Zanella Netto Feb. 6, 2025, 7:48 p.m. UTC | #2
On 06/02/25 16:34, Adhemerval Zanella Netto wrote:
> 
> 
> On 29/01/25 06:49, Yury Khrustalev wrote:
>> ---
>>  configure    | 36 ++++++++++++++++++++++++++++++++++++
>>  configure.ac |  5 +++++
>>  2 files changed, 41 insertions(+)
>>
>> diff --git a/configure b/configure
>> index eb8abd0054..19cae4aec7 100755
>> --- a/configure
>> +++ b/configure
>> @@ -8908,6 +8908,42 @@ printf "%s\n" "$libc_linker_feature" >&6; }
>>  config_vars="$config_vars
>>  load-address-ldflag = $libc_cv_load_address_ldflag"
>>  
>> +# 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_test_gcs=yes
>> +else
>> +  libc_cv_test_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-test-cc-gcs = $libc_cv_test_gcs"
>> +
>>  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5
>>  printf %s "checking if we can build programs as PIE... " >&6; }
>>  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
>> diff --git a/configure.ac b/configure.ac
>> index 050bfa65e3..4c30d5a5b7 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -1992,6 +1992,11 @@ 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 linker supports GCS marking
>> +LIBC_LINKER_FEATURE([-z gcs=always], [-Wl,-z,gcs=always],
>> +		    [libc_cv_test_gcs=yes], [libc_cv_test_gcs=no])
>> +LIBC_CONFIG_VAR([have-test-cc-gcs], [$libc_cv_test_gcs])
>> +
> 
> I think we might also need to check if compiler will ending using -z gcs
> as well, otherwise users might still some failures if glibc itself it
> not built with gcs.
> 
> For instance, with gcc 14 either with or without --enable-standard-branch-protection
> (where gcs is support), but with a gcs enabled binutils (so have-test-cc-gcs is yes)

I meant where gcs is *not* supported, with gcc-15 I don't see this issue (but I
still need to check with a build without --enable-standard-branch-protection).

> I see failures because at loading time libc.so.6 is not GCS compatible.
> 
> Maybe filtering out such failures (to check libc.so.6 it no GCS compatible), but it
> also means that GCS won't be usable anyway.
> 
>>  AC_MSG_CHECKING(if we can build programs as PIE)
>>  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED
>>  # error PIE is not supported
>
  
Yury Khrustalev Feb. 10, 2025, 11:48 a.m. UTC | #3
Hello Adhemerval,

On Thu, Feb 06, 2025 at 04:48:33PM -0300, Adhemerval Zanella Netto wrote:
> 
> 
> On 06/02/25 16:34, Adhemerval Zanella Netto wrote:
> > 
> > 
> > On 29/01/25 06:49, Yury Khrustalev wrote:
> >> ---
> >>  configure    | 36 ++++++++++++++++++++++++++++++++++++
> >>  configure.ac |  5 +++++
> >>  2 files changed, 41 insertions(+)
> >>
> >> +# Check if linker supports GCS marking
> >> +LIBC_LINKER_FEATURE([-z gcs=always], [-Wl,-z,gcs=always],
> >> +		    [libc_cv_test_gcs=yes], [libc_cv_test_gcs=no])
> >> +LIBC_CONFIG_VAR([have-test-cc-gcs], [$libc_cv_test_gcs])
> >> +
> > 
> > I think we might also need to check if compiler will ending using -z gcs
> > as well, otherwise users might still some failures if glibc itself it
> > not built with gcs.
> > 
> > For instance, with gcc 14 either with or without --enable-standard-branch-protection
> > (where gcs is support), but with a gcs enabled binutils (so have-test-cc-gcs is yes)
> 
> I meant where gcs is *not* supported, with gcc-15 I don't see this issue (but I
> still need to check with a build without --enable-standard-branch-protection).
> 
> > I see failures because at loading time libc.so.6 is not GCS compatible.
> > 
> > Maybe filtering out such failures (to check libc.so.6 it no GCS compatible), but it
> > also means that GCS won't be usable anyway.
> > 
> >>  AC_MSG_CHECKING(if we can build programs as PIE)
> >>  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED
> >>  # error PIE is not supported
> > 

I agree this is better to check both compiler and linker support and only
enabled the new tests when all toolchain components support GCS.

I've sent v4 with the requested changes:
https://inbox.sourceware.org/libc-alpha/20250210114538.1723249-1-yury.khrustalev@arm.com/

Thanks,
Yury
  

Patch

diff --git a/configure b/configure
index eb8abd0054..19cae4aec7 100755
--- a/configure
+++ b/configure
@@ -8908,6 +8908,42 @@  printf "%s\n" "$libc_linker_feature" >&6; }
 config_vars="$config_vars
 load-address-ldflag = $libc_cv_load_address_ldflag"
 
+# 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_test_gcs=yes
+else
+  libc_cv_test_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-test-cc-gcs = $libc_cv_test_gcs"
+
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can build programs as PIE" >&5
 printf %s "checking if we can build programs as PIE... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
diff --git a/configure.ac b/configure.ac
index 050bfa65e3..4c30d5a5b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1992,6 +1992,11 @@  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 linker supports GCS marking
+LIBC_LINKER_FEATURE([-z gcs=always], [-Wl,-z,gcs=always],
+		    [libc_cv_test_gcs=yes], [libc_cv_test_gcs=no])
+LIBC_CONFIG_VAR([have-test-cc-gcs], [$libc_cv_test_gcs])
+
 AC_MSG_CHECKING(if we can build programs as PIE)
 AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifdef PIE_UNSUPPORTED
 # error PIE is not supported