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.

Reply via email to