Matthieu Longo <matthieu.lo...@arm.com> writes: > 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, those metadata, used for the previously mentioned > runtime checks, have been provided to the runtime linker via GNU > properties which are stored in the ELF section ".note.gnu.property". > 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 (a.k.a. BAs). > > This patch adds the support for emitting AArch64 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=[standard|...] > is passed: > - If the assembler support BAs, GCC emits the BAs directives and > no GNU properties. Note: the static linker will derive the values > of GNU properties from the BAs, and will emit both BAs and GNU > properties into the output object. > - If the assembler do not support them, only .note.gnu.property > section will contain the relevant information. > > Bootstrapped on aarch64-none-linux-gnu, and no regression found. > > [1]: https://github.com/ARM-software/abi-aa/pull/230 > > gcc/ChangeLog: > > * config.in: Regenerate. > * config/aarch64/aarch64-dwarf-metadata.h > (class aeabi_subsection): New class for BAs. > * config/aarch64/aarch64-protos.h > (aarch64_pacret_enabled): New function. > * config/aarch64/aarch64.cc > (HAVE_AS_AEABI_BUILD_ATTRIBUTES): New definition. > (aarch64_file_end_indicate_exec_stack): Emit BAss. > (aarch64_pacret_enabled): New function. > (aarch64_start_file): > * configure: Regenerate. > * configure.ac: New configure check for BAs support in binutils. > > gcc/testsuite/ChangeLog: > > * lib/target-supports.exp: > (check_effective_target_aarch64_gas_has_build_attributes): New checker. > * gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp: New > DejaGNU file. > * gcc.target/aarch64/build-attributes/build-attribute-bti.c: New test. > * gcc.target/aarch64/build-attributes/build-attribute-gcs.c: New test. > * gcc.target/aarch64/build-attributes/build-attribute-pac.c: New test. > * gcc.target/aarch64/build-attributes/build-attribute-standard.c: New > test. > * 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. > > Co-Authored-By: Srinath Parvathaneni <srinath.parvathan...@arm.com>
Same comment as patch 2 about the copyright dates. OK with that change, thanks. Looks really nice! Richard > --- > gcc/config.in | 6 + > gcc/config/aarch64/aarch64-dwarf-metadata.h | 206 ++++++++++++++++++ > gcc/config/aarch64/aarch64-protos.h | 1 + > gcc/config/aarch64/aarch64.cc | 49 ++++- > gcc/configure | 37 ++++ > gcc/configure.ac | 9 + > .../aarch64-build-attributes.exp | 35 +++ > .../build-attributes/build-attribute-bti.c | 11 + > .../build-attributes/build-attribute-gcs.c | 11 + > .../build-attributes/build-attribute-pac.c | 11 + > .../build-attribute-standard.c | 13 ++ > .../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 + > gcc/testsuite/lib/target-supports.exp | 15 ++ > 16 files changed, 443 insertions(+), 9 deletions(-) > create mode 100644 > gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp > create mode 100644 > gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c > 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-pac.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/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 > > diff --git a/gcc/config.in b/gcc/config.in > index a79c51adb2b..ab62c1566cb 100644 > --- a/gcc/config.in > +++ b/gcc/config.in > @@ -355,6 +355,12 @@ > #endif > > > +/* Define if your assembler supports AEABI build attributes. */ > +#ifndef USED_FOR_TARGET > +#undef HAVE_AS_AEABI_BUILD_ATTRIBUTES > +#endif > + > + > /* Define if your assembler supports architecture modifiers. */ > #ifndef USED_FOR_TARGET > #undef HAVE_AS_ARCHITECTURE_MODIFIERS > diff --git a/gcc/config/aarch64/aarch64-dwarf-metadata.h > b/gcc/config/aarch64/aarch64-dwarf-metadata.h > index ab28283aecb..a5827943714 100644 > --- a/gcc/config/aarch64/aarch64-dwarf-metadata.h > +++ b/gcc/config/aarch64/aarch64-dwarf-metadata.h > @@ -21,6 +21,8 @@ > #ifndef GCC_AARCH64_DWARF_METADATA_H > #define GCC_AARCH64_DWARF_METADATA_H > > +#include "vec.h" > + > namespace aarch64 { > > class section_note_gnu_property > @@ -42,6 +44,210 @@ class section_note_gnu_property > unsigned m_feature_1_and; > }; > > +enum subsection_optionality : uint8_t > +{ > + required = 0x0, > + optional = 0x1, > +}; > + > +enum subsection_val_type : uint8_t > +{ > + uleb128 = 0x0, > + ntbs = 0x1, > +}; > + > +enum BA_TagFeature_t : uint8_t > +{ > + Tag_Feature_BTI = 0, > + Tag_Feature_PAC = 1, > + Tag_Feature_GCS = 2, > +}; > + > +template <typename T_tag, typename T_val> > +struct aeabi_attribute > +{ > + T_tag tag; > + T_val value; > +}; > + > +template <typename T_tag, typename T_val> > +aeabi_attribute<T_tag, T_val> > +make_aeabi_attribute (T_tag tag, T_val val) > +{ > + return aeabi_attribute<T_tag, T_val>{tag, val}; > +} > + > +namespace details { > + > +constexpr const char * > +to_c_str (bool b) > +{ > + return b ? "true" : "false"; > +} > + > +constexpr const char * > +to_c_str (const char *s) > +{ > + return s; > +} > + > +constexpr const char * > +to_c_str (subsection_optionality v) > +{ > + return (v == optional ? "optional" > + : v == required ? "required" > + : nullptr); > +} > + > +constexpr const char * > +to_c_str (subsection_val_type v) > +{ > + return (v == uleb128 ? "ULEB128" > + : v == ntbs ? "NTBS" > + : nullptr); > +} > + > +constexpr const char * > +to_c_str (BA_TagFeature_t feature) > +{ > + return (feature == Tag_Feature_BTI ? "Tag_Feature_BTI" > + : feature == Tag_Feature_PAC ? "Tag_Feature_PAC" > + : feature == Tag_Feature_GCS ? "Tag_Feature_GCS" > + : nullptr); > +} > + > +template < > + typename T, > + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type > +> > +constexpr const char * > +aeabi_attr_str_fmt (T) > +{ > + return "\t.aeabi_attribute %s, %u"; > +} > + > +constexpr const char * > +aeabi_attr_str_fmt (const char *) > +{ > + return "\t.aeabi_attribute %s, \"%s\""; > +} > + > +template < > + typename T, > + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type > +> > +constexpr uint8_t > +aeabi_attr_val_for_fmt (T value) > +{ > + return static_cast<uint8_t>(value); > +} > + > +constexpr const char * > +aeabi_attr_val_for_fmt (const char *s) > +{ > + return s; > +} > + > +template <typename T_tag, typename T_val> > +void > +write (FILE *out_file, aeabi_attribute<T_tag, T_val> const &attr) > +{ > + asm_fprintf (out_file, aeabi_attr_str_fmt (T_val{}), > + to_c_str (attr.tag), aeabi_attr_val_for_fmt (attr.value)); > + if (flag_debug_asm) > + asm_fprintf (out_file, "\t%s %s: %s", ASM_COMMENT_START, > + to_c_str (attr.tag), to_c_str (attr.value)); > + asm_fprintf (out_file, "\n"); > +} > + > +template < > + typename T, > + typename = typename std::enable_if<std::is_unsigned<T>::value, T>::type > +> > +constexpr subsection_val_type > +deduce_attr_av_type (T) > +{ > + return subsection_val_type::uleb128; > +} > + > +constexpr subsection_val_type > +deduce_attr_av_type (const char *) > +{ > + return subsection_val_type::ntbs; > +} > + > +} // namespace details > + > +/* AEABI subsections can be public or private. A subsection is public if it > is > + prefixed with "aeabi", private otherwise. The header of an AEABI > subsection > + is composed of a name (usually a vendor name), an optionality status > (optional > + or required), and the expected type of its associated attributes (ULEB128 > or > + NTBS). Note: The attributes in the same subsection have all the same > type. > + An attribute is composed of a tag identifier (ULEB128), and its value > (ULEB128 > + or NTBS). > + > + Syntax: > + .aeabi_subsection NameOfTheSubsection: string (=NTBS), > + Optional: boolean (=ULEB128), > + AttributeValueType: enum{ULEB128, NTBS} (=ULEB128) > + [ > + .aeabi_attribute TagIdentifier: ULEB128, > + TagValue: Variant[ULEB128|NTBS] > + ]* > + > + Example: > + .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 > + .aeabi_attribute Tag_Feature_GCS, 1 // Tag_Feature_GCS: true > + > + Note: The textual representations of the tag and its value are emitted as > a > + comment along their numerical representations to annotate the assembler > + output when the developer flag '-dA' is provided. */ > +template < > + typename T_tag, /* The type of a tag. */ > + typename T_val, /* The type of a value. */ > + size_t N = 0 /* The number of expected attributes if we know it. */ > +> > +class aeabi_subsection > +{ > + public: > + aeabi_subsection (const char *name, bool optional) > + : m_name (name), > + m_optionality (optional > + ? subsection_optionality::optional > + : subsection_optionality::required), > + m_avtype (details::deduce_attr_av_type (T_val{})) > + {} > + > + /* Append an attribute to the subsection. */ > + void append (aeabi_attribute<T_tag, T_val> &&attr) > + { > + m_attributes.quick_push (std::move (attr)); > + } > + > + /* Write the data to the assembly file. */ > + void write (FILE *out_file) const > + { > + asm_fprintf (out_file, "\n\t.aeabi_subsection %s, %s, %s\n", > + m_name, details::to_c_str (m_optionality), > + details::to_c_str (m_avtype)); > + > + for (auto const &attr : m_attributes) > + details::write (out_file, attr); > + } > + > + /* Indicate if the subsection is empty. */ > + bool empty () const > + { > + return m_attributes.is_empty (); > + } > + > + private: > + const char *m_name; > + subsection_optionality m_optionality; > + subsection_val_type m_avtype; > + auto_vec<aeabi_attribute<T_tag, T_val>, N> m_attributes; > +}; > + > } // namespace aarch64 > > #endif /* GCC_AARCH64_DWARF_METADATA_H */ > diff --git a/gcc/config/aarch64/aarch64-protos.h > b/gcc/config/aarch64/aarch64-protos.h > index 8f37e56d440..b1ce42fc396 100644 > --- a/gcc/config/aarch64/aarch64-protos.h > +++ b/gcc/config/aarch64/aarch64-protos.h > @@ -1267,6 +1267,7 @@ void aarch64_expand_reversed_crc_using_pmull > (scalar_mode, scalar_mode, rtx *); > > void aarch64_expand_fp_spaceship (rtx, rtx, rtx, rtx); > > +extern bool aarch64_pacret_enabled (); > extern bool aarch64_gcs_enabled (); > > extern unsigned aarch64_data_alignment (const_tree exp, unsigned align); > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index fe5f2c1250f..99981e6024c 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -109,6 +109,10 @@ > and 1 MOVI/DUP (same size as a call). */ > #define MAX_SET_SIZE(speed) (speed ? 256 : 96) > > +#ifndef HAVE_AS_AEABI_BUILD_ATTRIBUTES > +#define HAVE_AS_AEABI_BUILD_ATTRIBUTES 0 > +#endif > + > /* Flags that describe how a function shares certain architectural state > with its callers. > > @@ -8757,6 +8761,13 @@ aarch_bti_j_insn_p (rtx_insn *insn) > return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J; > } > > +/* Return TRUE if Pointer Authentication for the return address is enabled. > */ > +bool > +aarch64_pacret_enabled (void) > +{ > + return (aarch_ra_sign_scope != AARCH_FUNCTION_NONE); > +} > + > /* Return TRUE if Guarded Control Stack is enabled. */ > bool > aarch64_gcs_enabled (void) > @@ -25356,7 +25367,6 @@ aarch64_start_file (void) > } > > /* Emit load exclusive. */ > - > static void > aarch64_emit_load_exclusive (machine_mode mode, rtx rval, > rtx mem, rtx model_rtx) > @@ -29992,16 +30002,37 @@ aarch64_file_end_indicate_exec_stack () > { > file_end_indicate_exec_stack (); > > - aarch64::section_note_gnu_property gnu_properties; > + /* Check whether the current assembler supports AEABI build attributes, if > + not fallback to .note.gnu.property section. */ > + if (HAVE_AS_AEABI_BUILD_ATTRIBUTES) > + { > + using namespace aarch64; > + aeabi_subsection<BA_TagFeature_t, bool, 3> > + aeabi_subsec ("aeabi_feature_and_bits", true); > > - if (aarch_bti_enabled ()) > - gnu_properties.bti_enabled (); > - if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE) > - gnu_properties.pac_enabled (); > - if (aarch64_gcs_enabled ()) > - gnu_properties.gcs_enabled (); > + aeabi_subsec.append ( > + make_aeabi_attribute (Tag_Feature_BTI, aarch_bti_enabled ())); > + aeabi_subsec.append ( > + make_aeabi_attribute (Tag_Feature_PAC, aarch64_pacret_enabled ())); > + aeabi_subsec.append ( > + make_aeabi_attribute (Tag_Feature_GCS, aarch64_gcs_enabled ())); > > - gnu_properties.write (); > + if (!aeabi_subsec.empty ()) > + aeabi_subsec.write (asm_out_file); > + } > + else > + { > + aarch64::section_note_gnu_property gnu_properties; > + > + if (aarch_bti_enabled ()) > + gnu_properties.bti_enabled (); > + if (aarch64_pacret_enabled ()) > + gnu_properties.pac_enabled (); > + if (aarch64_gcs_enabled ()) > + gnu_properties.gcs_enabled (); > + > + gnu_properties.write (); > + } > } > > /* Helper function for straight line speculation. > diff --git a/gcc/configure b/gcc/configure > index 776b0628c60..f056cfe9677 100755 > --- a/gcc/configure > +++ b/gcc/configure > @@ -28247,6 +28247,43 @@ 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 AEABI build attributes. > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for support > of AEABI build attributes" >&5 > +$as_echo_n "checking assembler for support of AEABI build attributes... " > >&6; } > +if ${gcc_cv_as_aarch64_aeabi_build_attributes+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + gcc_cv_as_aarch64_aeabi_build_attributes=no > + if test x$gcc_cv_as != x; then > + $as_echo ' > + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 > + .aeabi_attribute Tag_Feature_BTI, 1 > + .aeabi_attribute Tag_Feature_PAC, 1 > + .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_aeabi_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_aeabi_build_attributes" >&5 > +$as_echo "$gcc_cv_as_aarch64_aeabi_build_attributes" >&6; } > +if test $gcc_cv_as_aarch64_aeabi_build_attributes = yes; then > + > +$as_echo "#define HAVE_AS_AEABI_BUILD_ATTRIBUTES 1" >>confdefs.h > + > fi > > # Enable Branch Target Identification Mechanism and Return Address > diff --git a/gcc/configure.ac b/gcc/configure.ac > index b6db9edfc83..58bf63f8be9 100644 > --- a/gcc/configure.ac > +++ b/gcc/configure.ac > @@ -4467,6 +4467,15 @@ 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 AEABI build attributes. > + gcc_GAS_CHECK_FEATURE([support of AEABI build attributes], > gcc_cv_as_aarch64_aeabi_build_attributes,, > + [ > + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 > + .aeabi_attribute Tag_Feature_BTI, 1 > + .aeabi_attribute Tag_Feature_PAC, 1 > + .aeabi_attribute Tag_Feature_GCS, 1 > + ],,[AC_DEFINE(HAVE_AS_AEABI_BUILD_ATTRIBUTES, 1, > + [Define if your assembler supports AEABI 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/aarch64-build-attributes.exp > > b/gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp > new file mode 100644 > index 00000000000..d0caf81c0cf > --- /dev/null > +++ > b/gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp > @@ -0,0 +1,35 @@ > +# 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 > + > +# Main loop. > +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ > + "" "" > + > +# All done. > +dg-finish > diff --git > a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c > b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c > new file mode 100644 > index 00000000000..363a6de56ab > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile { target { aarch64*-*-linux* && { > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=bti -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, > optional, ULEB128" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_BTI, 1\t\/\/ > Tag_Feature_BTI: true" } } */ > +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ > 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..5368915a133 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile { target { aarch64*-*-linux* && { > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=gcs -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, > optional, ULEB128" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_GCS, 1\t\/\/ > Tag_Feature_GCS: true" } } */ > +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ > diff --git > a/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c > b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c > new file mode 100644 > index 00000000000..79d36c1af2d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile { target { aarch64*-*-linux* && { > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=pac-ret -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, > optional, ULEB128" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_PAC, 1\t\/\/ > Tag_Feature_PAC: true" } } */ > +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ > 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..7ffa717c63c > --- /dev/null > +++ > b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c > @@ -0,0 +1,13 @@ > +/* { dg-do compile { target { aarch64*-*-linux* && > aarch64_gas_has_build_attributes } } } */ > +/* { dg-options "-mbranch-protection=standard -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler "\.aeabi_subsection aeabi_feature_and_bits, > optional, ULEB128" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_BTI, 1\t\/\/ > Tag_Feature_BTI: true" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_PAC, 1\t\/\/ > Tag_Feature_PAC: true" } } */ > +/* { dg-final { scan-assembler "\.aeabi_attribute Tag_Feature_GCS, 1\t\/\/ > Tag_Feature_GCS: true" } } */ > +/* { dg-final { scan-assembler-not "\.section\t\.note\.gnu\.property" } } */ > 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..013c76e5a2a > --- /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* && { ! > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=bti -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ > +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ > +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ > +/* { dg-final { scan-assembler "\.word\t0x1\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..954bf3ac8c3 > --- /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* && { ! > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=gcs -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ > +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ > +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ > +/* { dg-final { scan-assembler "\.word\t0x4\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..10195ecdbd9 > --- /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* && { ! > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=pac-ret -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ > +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ > +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ > +/* { dg-final { scan-assembler "\.word\t0x2\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..52cad2863f2 > --- /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* && { ! > aarch64_gas_has_build_attributes } } } } */ > +/* { dg-options "-mbranch-protection=standard -dA" } */ > + > +int main() > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-not "\.aeabi_subsection" } } */ > +/* { dg-final { scan-assembler-not "\.aeabi_attribute" } } */ > +/* { dg-final { scan-assembler "\.section\t\.note\.gnu\.property" } } */ > +/* { dg-final { scan-assembler "\.word\t0x7\t\/\/ > GNU_PROPERTY_AARCH64_FEATURE_1_AND \\(BTI, PAC, GCS\\)" } } */ > \ No newline at end of file > diff --git a/gcc/testsuite/lib/target-supports.exp > b/gcc/testsuite/lib/target-supports.exp > index dfffe3adfbd..82e5c31e499 100644 > --- a/gcc/testsuite/lib/target-supports.exp > +++ b/gcc/testsuite/lib/target-supports.exp > @@ -12442,6 +12442,21 @@ proc check_effective_target_aarch64_tiny { } { > } > } > > +# Return 1 if Gas supports AEABI build attributes on AArch64 target > +proc check_effective_target_aarch64_gas_has_build_attributes { } { > + if { ![istarget aarch64*-*-*] } { > + return 0 > + } > + > + return [check_no_compiler_messages aarch64_gas_has_build_attributes > object { > + /* Assembly */ > + .aeabi_subsection aeabi_feature_and_bits, optional, ULEB128 > + .aeabi_attribute Tag_Feature_BTI, 1 > + .aeabi_attribute Tag_Feature_PAC, 1 > + .aeabi_attribute Tag_Feature_GCS, 1 > + }] > +} > + > # Create functions to check that the AArch64 assembler supports the > # various architecture extensions via the .arch_extension pseudo-op.