[PATCH v0] aarch64: silence GCS warnings on shared libraries for -z gcs=implicit

Srinath Parvathaneni srinath.parvathaneni@arm.com
Mon Dec 8 11:41:25 GMT 2025


Hi Matthieu,

Please find my comments below.

On 12/5/25 16:33, Matthieu Longo wrote:
> Dynamic library incompatibilities should not be reported when
> '-z gcs=implicit' is used and no '-z gcs-report-dynamic' option is
> provided. However, '-z gcs=always' continues to default to reporting
> these as warnings.
> 
> Binary Linux distributions do not rebuild all packages from scratch
> when rolling out a new feature or creating a new release; only
> modified packages get rebuilt. In the context of GCS deployment, this
> meant that some packages were rebuilt with GCS enabled while their
> dependencies were not yet GCS-compatible, resulting in warnings. These
> warnings caused build failures for packages that treat linker warnings
> as errors.
> 
> This patch preserves the existing inheritance of the value from
> '-z gcs-report' if the option '-z gcs-report-dynamic' is not set on
> the command line, but it forces the value of '-z gcs-report-dynamic'
> to 'none' when '-z gcs=implicit' is used.
> It also adapts the existing tests for '-z gcs=implicit' to reflect
> this change, and adds new tests covering cases with no report option
> provided, or with '-z gcs-report-dynamic' explicitly set.
> ---
>   bfd/elfnn-aarch64.c                           | 29 ++++++++++++++++---
>   ld/ld.texi                                    |  4 ++-
>   .../ld-aarch64/protections/gcs-dynamic-3-a.d  | 15 +++-------
>   .../ld-aarch64/protections/gcs-dynamic-3-b.d  |  6 ++--
>   .../ld-aarch64/protections/gcs-dynamic-3-c.d  |  6 ++--
>   .../ld-aarch64/protections/gcs-dynamic-3-d.d  | 12 ++++++++
>   .../ld-aarch64/protections/gcs-dynamic-3-e.d  | 12 ++++++++
>   .../ld-aarch64/protections/gcs-dynamic-3-f.d  | 12 ++++++++
>   8 files changed, 74 insertions(+), 22 deletions(-)
>   create mode 100644 ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-d.d
>   create mode 100644 ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-e.d
>   create mode 100644 ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-f.d
> 
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index b104e40d1ab..6cd96b04908 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -5061,10 +5061,31 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
>        libraries, '-z gcs-report-dynamic=error' will have to be specified
>        explicitly.  */
>     if (sw_protections->gcs_report_dynamic == MARKING_UNSET)
> -    elf_aarch64_tdata (output_bfd)->sw_protections.gcs_report_dynamic
> -      = (sw_protections->gcs_report == MARKING_ERROR)
> -      ? MARKING_WARN
> -      : sw_protections->gcs_report;
> +    {
> +      aarch64_feature_marking_report *gcs_report_dynamic
> +	= &elf_aarch64_tdata (output_bfd)->sw_protections.gcs_report_dynamic;

This initialization of gcs_report_dynamic is overwritten by the very 
next assignment, so the declaration of the pointer itself is sufficient.

> +
> +      *gcs_report_dynamic
> +	= (sw_protections->gcs_report == MARKING_ERROR)
> +	? MARKING_WARN
> +	: sw_protections->gcs_report;
> +
> +
> +      /* Dynamic library incompatibilities must not be reported when
> +	 '-z gcs=implicit' is used and no '-z gcs-report-dynamic' option is
> +	 provided.  Instead this last must default to 'MARKING_NONE'.  However,
> +	 '-z gcs=always' continues to default to reporting these as warnings.

 > "Instead this last must default to 'MARKING_NONE'."
For clarity, perhaps replace “this last” with an explicit reference:
“Instead, -z gcs-report-dynamic must default to MARKING_NONE.”

> +	 Binary Linux distributions do not rebuild all packages from scratch
> +	 when rolling out a new feature or creating a new release; only modified
> +	 packages get rebuilt.  In the context of GCS deployment, this meant
> +	 that some packages were rebuilt with GCS enabled while their
> +	 dependencies were not yet GCS-compatible, resulting in warnings.  These
> +	 warnings caused build failures for packages that treat linker warnings
> +	 as errors.  */
> +      if (sw_protections->gcs_type == GCS_IMPLICIT)
> +	*gcs_report_dynamic = MARKING_NONE;

To make the logic clearer and avoid redundant writes, this block could 
be structured as an if/else statement, e.g:

if (sw_protections->gcs_type == GCS_IMPLICIT)
   *gcs_report_dynamic = MARKING_NONE;
else
   {
     *gcs_report_dynamic =
       (sw_protections->gcs_report == MARKING_ERROR)
         ? MARKING_WARN
         : sw_protections->gcs_report;
   }


This makes it explicit that only one of the two assignments can occur, 
and avoids writing a value that is immediately overwritten.

> +    }
>   
>     elf_aarch64_tdata (output_bfd)->n_bti_issues = 0;
>     elf_aarch64_tdata (output_bfd)->n_gcs_issues = 0;
> diff --git a/ld/ld.texi b/ld/ld.texi
> index 8ff65ec64a7..49a5a95ab9e 100644
> --- a/ld/ld.texi
> +++ b/ld/ld.texi
> @@ -8397,7 +8397,9 @@ omitted, it inherits the value of @samp{-z gcs-report}. However, the inherited
>   value is capped to @samp{warning} as some user might want to only report errors
>   in the currently built module, and not the shared dependencies. It is therefore
>   necessary to use an explicit @samp{-z gcs-report-dynamic=error} option if you
> -want the linker to error on GCS issues in the shared libraries.
> +want the linker to error on GCS issues in the shared libraries. Additionally,
> +if @samp{-z gcs=implicit} is provided and the option is omitted, it will default
> +to @samp{none}.
>   @itemize
>   @item @samp{none} disables any warning messages.
>   @item @samp{warning} emits warning messages when dynamic objects are missing
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-a.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-a.d
> index ecdaf526779..dbe77bdad16 100644
> --- a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-a.d
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-a.d
> @@ -1,15 +1,8 @@
> -#name: '-z gcs=implicit -z gcs-report=error' and shared libraries without GCS feature reports warnings.
> +#name: '-z gcs=implicit -z gcs-report-dynamic=error' and shared libraries without GCS feature report errors.
>   #source: gcs.s
>   #source: gcs2.s
>   #alltargets: [check_shared_lib_support] *linux*
>   #as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> -#ld: -z gcs=implicit -z gcs-report=error -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> -#warning: \A[^\n]*libnogcs-so\.so: warning: GCS is required by -z gcs[^\n]*\n
> -#warning:   [^\n]*libbti-plt-so\.so: warning: GCS is required by -z gcs[^\n]*
> -
> -#readelf: -n
> -
> -Displaying notes found in: .note.gnu.property
> -[ 	]+Owner[ 	]+Data size[ 	]+Description
> -  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> -      Properties: AArch64 feature: GCS
> +#ld: -z gcs=implicit -z gcs-report-dynamic=error -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#error: \A[^\n]*libnogcs-so\.so: error: GCS is required by -z gcs[^\n]*\n
> +#error:   [^\n]*libbti-plt-so\.so: error: GCS is required by -z gcs[^\n]*
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-b.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-b.d
> index 4d32fb6aa54..29d632187fe 100644
> --- a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-b.d
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-b.d
> @@ -1,9 +1,9 @@
> -#name: '-z gcs=implicit -z gcs-report=warning' and shared libraries without GCS feature reports warnings.
> +#name: '-z gcs=implicit -z gcs-report-dynamic=warning' and shared libraries without GCS feature report warnings.
>   #source: gcs.s
>   #source: gcs2.s
>   #alltargets: [check_shared_lib_support] *linux*
>   #as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> -#ld: -z gcs=implicit -z gcs-report=warning -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#ld: -z gcs=implicit -z gcs-report-dynamic=warning -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
>   #warning: \A[^\n]*libnogcs-so\.so: warning: GCS is required by -z gcs[^\n]*\n
>   #warning:   [^\n]*libbti-plt-so\.so: warning: GCS is required by -z gcs[^\n]*
>   #readelf: -n
> @@ -11,4 +11,4 @@
>   Displaying notes found in: .note.gnu.property
>   [ 	]+Owner[ 	]+Data size[ 	]+Description
>     GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> -      Properties: AArch64 feature: GCS
> \ No newline at end of file
> +      Properties: AArch64 feature: GCS
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-c.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-c.d
> index c0da6c1d9c6..9bed95f75e0 100644
> --- a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-c.d
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-c.d
> @@ -1,12 +1,12 @@
> -#name: '-z gcs=implicit -z gcs-report=none' and shared libraries without GCS feature reports no warning.
> +#name: '-z gcs=implicit -z gcs-report-dynamic=none' and shared libraries without GCS feature report no warning.
>   #source: gcs.s
>   #source: gcs2.s
>   #alltargets: [check_shared_lib_support] *linux*
>   #as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> -#ld: -z gcs=implicit -z gcs-report=none -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#ld: -z gcs=implicit -z gcs-report-dynamic=none -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
>   #readelf: -n
>   
>   Displaying notes found in: .note.gnu.property
>   [ 	]+Owner[ 	]+Data size[ 	]+Description
>     GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> -      Properties: AArch64 feature: GCS
> \ No newline at end of file
> +      Properties: AArch64 feature: GCS
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-d.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-d.d
> new file mode 100644
> index 00000000000..cae27a25b7c
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-d.d
> @@ -0,0 +1,12 @@
> +#name: '-z gcs=implicit' without '-z gcs-report' or '-z gcs-report-dynamic' options and shared libraries without GCS feature report no warning.
> +#source: gcs.s
> +#source: gcs2.s
> +#alltargets: [check_shared_lib_support] *linux*
> +#as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> +#ld: -z gcs=implicit -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#readelf: -n
> +
> +Displaying notes found in: .note.gnu.property
> +[ 	]+Owner[ 	]+Data size[ 	]+Description
> +  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> +      Properties: AArch64 feature: GCS
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-e.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-e.d
> new file mode 100644
> index 00000000000..2ad9c3fc5be
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-e.d
> @@ -0,0 +1,12 @@
> +#name: '-z gcs=implicit -z gcs-report=error' and shared libraries without GCS feature report no warning.
> +#source: gcs.s
> +#source: gcs2.s
> +#alltargets: [check_shared_lib_support] *linux*
> +#as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> +#ld: -z gcs=implicit -z gcs-report=error -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#readelf: -n
> +
> +Displaying notes found in: .note.gnu.property
> +[ 	]+Owner[ 	]+Data size[ 	]+Description
> +  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> +      Properties: AArch64 feature: GCS
> diff --git a/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-f.d b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-f.d
> new file mode 100644
> index 00000000000..97c30e806c4
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/protections/gcs-dynamic-3-f.d
> @@ -0,0 +1,12 @@
> +#name: '-z gcs=implicit -z gcs-report=warning' and shared libraries without GCS feature report no warning.
> +#source: gcs.s
> +#source: gcs2.s
> +#alltargets: [check_shared_lib_support] *linux*
> +#as: -march=armv9.4-a+gcs  -defsym __property_gcs__=1
> +#ld: -z gcs=implicit -z gcs-report=warning -L./tmpdir -lnogcs-so -lbti-plt-so -lgcs-so2
> +#readelf: -n
> +
> +Displaying notes found in: .note.gnu.property
> +[ 	]+Owner[ 	]+Data size[ 	]+Description
> +  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
> +      Properties: AArch64 feature: GCS

Add please add a test for combination of '-z gcs=implicit -z gcs-report 
' and shared Libraries without GCS feature report, if not already present.

Regards,
Srinath


More information about the Binutils mailing list