[PATCH v2 2/4] aarch64: add minimal support of AEABI build attributes for GCS.
Matthieu Longo
matthieu.longo@arm.com
Wed Oct 23 10:35:58 GMT 2024
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 contain the relevant information.
This patch needs to be applied on top of GCC's 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
(HAVE_AS_AEABI_BUILD_ATTRIBUTES): New definition.
(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 a configure check for gcc.
gcc/testsuite/ChangeLog:
* lib/target-supports.exp:
(check_effective_target_aarch64_gas_has_build_attributes): New.
* 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/aarch64-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.
Co-Authored-By: Matthieu Longo <matthieu.longo@arm.com>
---
gcc/config.in | 6 +++
gcc/config/aarch64/aarch64.cc | 41 +++++++++++++++++++
gcc/configure | 38 +++++++++++++++++
gcc/configure.ac | 10 +++++
.../aarch64-build-attributes.exp | 35 ++++++++++++++++
.../build-attributes/build-attribute-gcs.c | 12 ++++++
.../build-attribute-standard.c | 12 ++++++
.../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 | 16 ++++++++
12 files changed, 218 insertions(+)
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-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/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 7fcabbe5061..0d54141ce30 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.cc b/gcc/config/aarch64/aarch64.cc
index 0466d6d11eb..90aba0fff88 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.
@@ -24783,6 +24787,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
@@ -24803,6 +24834,16 @@ aarch64_start_file (void)
asm_fprintf (asm_out_file, "\t.arch %s\n",
aarch64_last_printed_arch_string.c_str ());
+ /* Check whether the current assembly supports gcs build attributes, if not
+ fallback to .note.gnu.property section. */
+#if (HAVE_AS_AEABI_BUILD_ATTRIBUTES)
+ if (aarch64_gcs_enabled ())
+ {
+ aarch64_emit_aeabi_subsection (".aeabi-feature-and-bits", 1, 0);
+ aarch64_emit_aeabi_attribute ("Tag_Feature_GCS", 3, 1);
+ }
+#endif
+
default_file_start ();
}
diff --git a/gcc/configure b/gcc/configure
index 8ed47b4dadb..62d9ba4fdab 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -28035,6 +28035,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 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 '
+ .set ATTR_TYPE_uleb128, 0
+ .set ATTR_TYPE_asciz, 1
+ .set Tag_Feature_foo, 1
+ .aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+ .aeabi_attribute Tag_Feature_foo, 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 8a5fed516b3..f4b1343ca70 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4387,6 +4387,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 AEABI build attributes.
+ gcc_GAS_CHECK_FEATURE([support of AEABI build attributes], gcc_cv_as_aarch64_aeabi_build_attributes,,
+ [
+ .set ATTR_TYPE_uleb128, 0
+ .set ATTR_TYPE_asciz, 1
+ .set Tag_Feature_foo, 1
+ .aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+ .aeabi_attribute Tag_Feature_foo, 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-gcs.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-gcs.c
new file mode 100644
index 00000000000..26938d84dab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/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 "\.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\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/build-attribute-standard.c b/gcc/testsuite/gcc.target/aarch64/build-attributes/build-attribute-standard.c
new file mode 100644
index 00000000000..6a41b52d298
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/build-attributes/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 "\.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\t0x7\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/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 d113a08dff7..457aa71e860 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12031,6 +12031,22 @@ 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 */
+ .set ATTR_TYPE_uleb128, 0
+ .set ATTR_TYPE_asciz, 1
+ .set Tag_Feature_foo, 1
+ .aeabi_subsection .aeabi-feature-and-bits, 1, ATTR_TYPE_uleb128
+ .aeabi_attribute Tag_Feature_foo, 1
+ }]
+}
+
# Create functions to check that the AArch64 assembler supports the
# various architecture extensions via the .arch_extension pseudo-op.
--
2.47.0
More information about the Gcc-patches
mailing list