]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: add support for AEABI Build Attributes
authorMatthieu Longo <matthieu.longo@arm.com>
Wed, 11 Sep 2024 15:11:55 +0000 (16:11 +0100)
committerMatthieu Longo <matthieu.longo@arm.com>
Mon, 16 Jun 2025 13:23:12 +0000 (14:23 +0100)
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-elf-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): Indent.
* 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.parvathaneni@arm.com>
16 files changed:
gcc/config.in
gcc/config/aarch64/aarch64-elf-metadata.h
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.cc
gcc/configure
gcc/configure.ac
gcc/testsuite/gcc.target/aarch64/build-attributes/aarch64-build-attributes.exp [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-bti.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-pac.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-bti.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-gcs.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-pac.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/build-attributes/no-build-attribute-standard.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index a79c51adb2b3fe25775be9004f75bc1c8717dc14..ab62c1566cbb34ca6ecca7eaef6074514b235ad8 100644 (file)
 #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
index 499260d7fffb735b40d2f6d885f495cf6ab88d67..e99f6df999d99c22f8fae5797e4d9e2788096125 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef GCC_AARCH64_ELF_METADATA_H
 #define GCC_AARCH64_ELF_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_ELF_METADATA_H */
index 8f37e56d440e950d331e61484004f215a7802612..b1ce42fc39667dbcf3375ecab32cff5a7bc4b971 100644 (file)
@@ -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);
index cc3bcbcba9cb9954a959466426a42ad83df51476..a65552a062f94fde3ec8042755878d2861b94510 100644 (file)
    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)
@@ -25334,7 +25345,6 @@ aarch64_start_file (void)
 }
 
 /* Emit load exclusive.  */
-
 static void
 aarch64_emit_load_exclusive (machine_mode mode, rtx rval,
                             rtx mem, rtx model_rtx)
@@ -29970,16 +29980,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.
index 776b0628c6022b9dad08975ddd8ccad9b45a03ae..f056cfe9677e3de1cca7a649077eb54d16dab420 100755 (executable)
@@ -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
index b6db9edfc83c9b7396804be0f00c08569aeff05f..58bf63f8be9ea03c92dbdbcc5d43105a8c3d3f9f 100644 (file)
@@ -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 (file)
index 0000000..c106c93
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) 2024-2025 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 (file)
index 0000000..363a6de
--- /dev/null
@@ -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 (file)
index 0000000..5368915
--- /dev/null
@@ -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 (file)
index 0000000..79d36c1
--- /dev/null
@@ -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 (file)
index 0000000..7ffa717
--- /dev/null
@@ -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 (file)
index 0000000..013c76e
--- /dev/null
@@ -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 (file)
index 0000000..954bf3a
--- /dev/null
@@ -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 (file)
index 0000000..10195ec
--- /dev/null
@@ -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 (file)
index 0000000..52cad28
--- /dev/null
@@ -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
index dfffe3adfbdd0a12aefa25730e1ae7fb912c3f3b..82e5c31e4994ed9007ba2337af0f9d57b05f22c7 100644 (file)
@@ -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.