[v1,2/4] aarch64: add minimal support for GCS build attributes

Message ID 20240927144755.632627-3-matthieu.longo@arm.com
State New
Headers
Series aarch64: add minimal support for GCS build attributes |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Matthieu Longo Sept. 27, 2024, 2:47 p.m. UTC
  From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>

GCS (Guarded Control Stack, an Armv9.4-a extension) requires some
caution at runtime. The runtime linker needs to reason about the
compatibility of a set of relocable object files that might not have
been compiled with the same compiler.
Up until now, GNU properties are stored in a ELF section (.note.gnu.property)
and have been used for the previously mentioned runtime checks
performed by the linker. However, GNU properties are limited in
their expressibility, and a long-term commmitment was taken in the
ABI for the Arm architecture [1] to provide build attributes.

This patch adds a first support for AArch64 GCS build attributes.
This support includes generating two new assembler directives:
.aeabi_subsection and .aeabi_attribute. These directives are
generated as per the syntax mentioned in spec "Build Attributes for
the Arm® 64-bit Architecture (AArch64)" available at [1].

gcc/configure.ac now includes a new check to test whether the
assembler being used to build the toolchain supports these new
directives.
Two behaviors can be observed when -mbranch-protection=[gcs|standard]
is passed:
- If the assembler support them, the assembly directives are emitted
along the .note.gnu.property section for backward compatibility.
- If the assembler does not support them, only .note.gnu.property
section will emit the relevant information.

This patch needs to be applied on top of GCC gcs patch series [2].

Bootstrapped on aarch64-none-linux-gnu, and no regression found.

[1]: https://github.com/ARM-software/abi-aa/pull/230
[2]: https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/vendors/ARM/heads/gcs

gcc/ChangeLog:

    * config.in: Regenerated
    * config/aarch64/aarch64.cc (aarch64_emit_aeabi_attribute): New
    function declaration.
    (aarch64_emit_aeabi_subsection): Likewise.
    (aarch64_start_file): Emit gcs build attributes.
    (aarch64_file_end_indicate_exec_stack): Update gcs bit in
    note.gnu.property section.
    * configure: Regenerated.
    * configure.ac: Add gcc configure check.

gcc/testsuite/ChangeLog:

    * gcc.target/aarch64/build-attributes/build-attribute-gcs.c: New test.
    * gcc.target/aarch64/build-attributes/build-attribute-standard.c: New test.
    * gcc.target/aarch64/build-attributes/build-attributes.exp: New DejaGNU file.
    * gcc.target/aarch64/build-attributes/no-build-attribute-bti.c: New test.
    * gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c: New test.
    * gcc.target/aarch64/build-attributes/no-build-attribute-pac.c: New test.
    * gcc.target/aarch64/build-attributes/no-build-attribute-standard.c: New test.
---
 gcc/config.in                                 |  6 +++
 gcc/config/aarch64/aarch64.cc                 | 41 +++++++++++++++++
 gcc/configure                                 | 38 +++++++++++++++
 gcc/configure.ac                              | 10 ++++
 .../build-attributes/build-attribute-gcs.c    | 12 +++++
 .../build-attribute-standard.c                | 12 +++++
 .../build-attributes/build-attributes.exp     | 46 +++++++++++++++++++
 .../build-attributes/no-build-attribute-bti.c | 12 +++++
 .../build-attributes/no-build-attribute-gcs.c | 12 +++++
 .../build-attributes/no-build-attribute-pac.c | 12 +++++
 .../no-build-attribute-standard.c             | 12 +++++
 11 files changed, 213 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c
  

Comments

Richard Sandiford Oct. 8, 2024, 5:42 p.m. UTC | #1
Since this is an RFC, it would probably be more helpful to get review
comments about the design or the adherence to the spec.  I'll need to
look into things a bit more for that, though, so I'm afraid the below
is more implementation trivia.

Matthieu Longo <matthieu.longo@arm.com> writes:
> [...]
> diff --git a/gcc/config.in b/gcc/config.in
> index 7fcabbe5061..1309ba2b133 100644
> --- a/gcc/config.in
> +++ b/gcc/config.in
> @@ -379,6 +379,12 @@
>  #endif
>  
>  
> +/* Define if your assembler supports GCS build attributes. */
> +#ifndef USED_FOR_TARGET
> +#undef HAVE_AS_BUILD_ATTRIBUTES_GCS
> +#endif

How about making this HAVE_AS_BUILD_AEABI_ATTRIBUTE?  Or is the idea
that each feature that uses build attributes would need its own
configure check?

> [...]
> @@ -24697,6 +24724,20 @@ aarch64_start_file (void)
>     asm_fprintf (asm_out_file, "\t.arch %s\n",
>  		aarch64_last_printed_arch_string.c_str ());
>  
> +/* Emit gcs build attributes only when building a native AArch64-hosted
> +   compiler.  */
> +#if defined(__aarch64__)

Why is this restricted to native compilers?  We should avoid that
if at all possible.

> +  /* Check the current assembly supports gcs build attributes, if not

"Check whether the current assembler supports..."

> +     fallback to .note.gnu.property section.  */
> +  #ifdef HAVE_AS_BUILD_ATTRIBUTES_GCS

It would be good to add:

#ifndef HAVE_AS_BUILD_ATTRIBUTES_GCS
#define HAVE_AS_BUILD_ATTRIBUTES_GCS 0
#endif

somewhere, so that we can use HAVE_AS_BUILD_ATTRIBUTES_GCS in C++
conditions as well as preprocessor conditions.

> +    if (aarch64_gcs_enabled ())
> +      {
> +	aarch64_emit_aeabi_subsection (".aeabi-feature-and-bits", 1, 0);
> +	aarch64_emit_aeabi_attribute ("Tag_Feature_GCS", 3, 1);
> +      }
> +  #endif
> +#endif
> +
>     default_file_start ();
>  }
> [...]
> diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp
> new file mode 100644
> index 00000000000..ea47e209227
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp
> @@ -0,0 +1,46 @@
> +# Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +# GCC testsuite that uses the `dg.exp' driver.
> +
> +# Exit immediately if this isn't an AArch64 target.
> +if ![istarget aarch64*-*-*] then {
> +  return
> +}
> +
> +# Load support procs.
> +load_lib gcc-dg.exp
> +
> +# Initialize `dg'.
> +dg-init
> +
> +proc check_effective_target_gas_has_build_attributes { } {
> +    return [check_no_compiler_messages gas_has_build_attributes object {
> +	/* Assembly */
> +	.set ATTR_TYPE_uleb128,   0
> +	.set ATTR_TYPE_asciz,     1
> +	.set Tag_Feature_GCS,     3
> +	.aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
> +	.aeabi_attribute Tag_Feature_GCS, 1
> +    }]
> +}

This should go in lib/target-supports.exp instead, probably as
"aarch64_gas_has...".

> +
> +# Main loop.
> +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
> +	"" ""
> +
> +# All done.
> +dg-finish
> diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c
> new file mode 100644
> index 00000000000..a8712d949f0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile { target { aarch64*-*-linux* && { ! gas_has_build_attributes } } } } */
> +/* { dg-options "-mbranch-protection=bti -dA" } */
> +
> +int main()
> +{
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-not "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
> +/* { dg-final { scan-assembler-not "\.aeabi_attribute 1, 1\t\/\/ Tag_Feature_BTI" } } */

For -not tests, it probably makes sense to test only for:

/* { dg-final { scan-assembler-not "\.aeabi_subsection " } } */
/* { dg-final { scan-assembler-not "\.aeabi_attribute " } } */

That is, we want to avoid emitting these directives at all, rather than
avoid emitting specific arguments/operands.

Thanks,
Richard

> +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
> +/* { dg-final { scan-assembler "\.word\t1\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI\\)" } } */
> \ No newline at end of file
  

Patch

diff --git a/gcc/config.in b/gcc/config.in
index 7fcabbe5061..1309ba2b133 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -379,6 +379,12 @@ 
 #endif
 
 
+/* Define if your assembler supports GCS build attributes. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_BUILD_ATTRIBUTES_GCS
+#endif
+
+
 /* Define to the level of your assembler's compressed debug section support.
    */
 #ifndef USED_FOR_TARGET
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 6d9075011ec..61e0248817f 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -24677,6 +24677,33 @@  aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
 	asm_fprintf (f, "\t.cfi_b_key_frame\n");
 }
 
+/* This function is used to emit an AEABI attribute with tag and its associated
+   value.  We emit the numerical value of the tag and the textual tags as
+   comment so that anyone reading the assembler output will know which tag is
+   being set.
+   example: .aeabi_attribute 3, 1 // Tag_Feature_GCS  */
+
+void
+aarch64_emit_aeabi_attribute (const char *name, uint8_t num, uint8_t val)
+{
+  asm_fprintf (asm_out_file, "\t.aeabi_attribute %u, %u", num, val);
+  if (flag_debug_asm)
+    asm_fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, name);
+  asm_fprintf (asm_out_file, "\n");
+}
+
+/* This function is used to emit an AEABI subsection with vendor name,
+   optional status and value type.
+   example: .aeabi_subsection .aeabi-feature-and-bits, 1, 0  */
+
+void
+aarch64_emit_aeabi_subsection (const char *name, uint8_t num, uint8_t val)
+{
+  asm_fprintf (asm_out_file, "\t.aeabi_subsection %s, %u, %u\n",
+	       name, num, val);
+}
+
+
 /* Implements TARGET_ASM_FILE_START.  Output the assembly header.  */
 
 static void
@@ -24697,6 +24724,20 @@  aarch64_start_file (void)
    asm_fprintf (asm_out_file, "\t.arch %s\n",
 		aarch64_last_printed_arch_string.c_str ());
 
+/* Emit gcs build attributes only when building a native AArch64-hosted
+   compiler.  */
+#if defined(__aarch64__)
+  /* Check the current assembly supports gcs build attributes, if not
+     fallback to .note.gnu.property section.  */
+  #ifdef HAVE_AS_BUILD_ATTRIBUTES_GCS
+    if (aarch64_gcs_enabled ())
+      {
+	aarch64_emit_aeabi_subsection (".aeabi-feature-and-bits", 1, 0);
+	aarch64_emit_aeabi_attribute ("Tag_Feature_GCS", 3, 1);
+      }
+  #endif
+#endif
+
    default_file_start ();
 }
 
diff --git a/gcc/configure b/gcc/configure
index ec6124cb361..29b9ee149d8 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -28036,6 +28036,44 @@  if test $gcc_cv_as_aarch64_picreloc = yes; then
 
 $as_echo "#define HAVE_AS_SMALL_PIC_RELOCS 1" >>confdefs.h
 
+fi
+
+    # Check if we have binutils support for GCS build attributes.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for GCS build attributes support" >&5
+$as_echo_n "checking assembler for GCS build attributes support... " >&6; }
+if ${gcc_cv_as_aarch64_gcs_build_attributes+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_aarch64_gcs_build_attributes=no
+  if test x$gcc_cv_as != x; then
+    $as_echo '
+	.set ATTR_TYPE_uleb128,   0
+	.set ATTR_TYPE_asciz,     1
+	.set Tag_Feature_GCS,     3
+	.aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+	.aeabi_attribute Tag_Feature_GCS, 1
+    ' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags  -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_aarch64_gcs_build_attributes=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_aarch64_gcs_build_attributes" >&5
+$as_echo "$gcc_cv_as_aarch64_gcs_build_attributes" >&6; }
+if test $gcc_cv_as_aarch64_gcs_build_attributes = yes; then
+
+$as_echo "#define HAVE_AS_BUILD_ATTRIBUTES_GCS 1" >>confdefs.h
+
 fi
 
     # Enable Branch Target Identification Mechanism and Return Address
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d0b9865fc91..fdcbf856cc9 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4388,6 +4388,16 @@  case "$target" in
 	ldr     x0, [[x2, #:gotpage_lo15:globalsym]]
     ],,[AC_DEFINE(HAVE_AS_SMALL_PIC_RELOCS, 1,
 	[Define if your assembler supports relocs needed by -fpic.])])
+    # Check if we have binutils support for GCS build attributes.
+    gcc_GAS_CHECK_FEATURE([GCS build attributes support], gcc_cv_as_aarch64_gcs_build_attributes,,
+    [
+	.set ATTR_TYPE_uleb128,   0
+	.set ATTR_TYPE_asciz,     1
+	.set Tag_Feature_GCS,     3
+	.aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+	.aeabi_attribute Tag_Feature_GCS, 1
+    ],,[AC_DEFINE(HAVE_AS_BUILD_ATTRIBUTES_GCS, 1,
+	[Define if your assembler supports GCS build attributes.])])
     # Enable Branch Target Identification Mechanism and Return Address
     # Signing by default.
     AC_ARG_ENABLE(standard-branch-protection,
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c
new file mode 100644
index 00000000000..ce43a79c1d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && { gas_has_build_attributes } } } } */
+/* { dg-options "-mbranch-protection=gcs -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler "\.aeabi_attribute 3, 1\t\/\/ Tag_Feature_GCS" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t4\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(GCS\\)" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c
new file mode 100644
index 00000000000..fd175f8137f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && gas_has_build_attributes } } } */
+/* { dg-options "-mbranch-protection=standard -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler "\.aeabi_attribute 3, 1\t\/\/ Tag_Feature_GCS" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t7\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI, PAC, GCS\\)" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp
new file mode 100644
index 00000000000..ea47e209227
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attributes.exp
@@ -0,0 +1,46 @@ 
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an AArch64 target.
+if ![istarget aarch64*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+proc check_effective_target_gas_has_build_attributes { } {
+    return [check_no_compiler_messages gas_has_build_attributes object {
+	/* Assembly */
+	.set ATTR_TYPE_uleb128,   0
+	.set ATTR_TYPE_asciz,     1
+	.set Tag_Feature_GCS,     3
+	.aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+	.aeabi_attribute Tag_Feature_GCS, 1
+    }]
+}
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c
new file mode 100644
index 00000000000..a8712d949f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && { ! gas_has_build_attributes } } } } */
+/* { dg-options "-mbranch-protection=bti -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler-not "\.aeabi_attribute 1, 1\t\/\/ Tag_Feature_BTI" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t1\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI\\)" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c
new file mode 100644
index 00000000000..cbf6491c75e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && { ! gas_has_build_attributes } } } } */
+/* { dg-options "-mbranch-protection=gcs -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler-not "\.aeabi_attribute 3, 1\t\/\/ Tag_Feature_GCS" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t4\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(GCS\\)" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c
new file mode 100644
index 00000000000..ef434541edb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && { ! gas_has_build_attributes } } } } */
+/* { dg-options "-mbranch-protection=pac-ret -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler-not "\.aeabi_attribute 2, 1\t\/\/ Tag_Feature_PAC" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t2\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(PAC\\)" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c
new file mode 100644
index 00000000000..b97a8731fbf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile { target { aarch64*-*-linux* && { ! gas_has_build_attributes } } } } */
+/* { dg-options "-mbranch-protection=standard -dA" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "\.aeabi_subsection \.aeabi-feature-and-bits, 1, 0" } } */
+/* { dg-final { scan-assembler-not "\.aeabi_attribute 3, 1\t\/\/ Tag_Feature_GCS" } } */
+/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */
+/* { dg-final { scan-assembler "\.word\t7\t\/\/ GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI, PAC, GCS\\)" } } */
\ No newline at end of file