[2/2] arm: implement -mbranch-protection command line option

Message ID gkra6k438lp.fsf@arm.com
State New
Headers
Series [1/2] arm: add arm bti pass |

Commit Message

Andrea Corallo Sept. 22, 2021, 3:58 p.m. UTC
  Hi all,

second patch of a series that enables Armv8.1-M in GCC adding Branch
Target Identification Mechanism [1].

This patch implements the -mbranch-protection option. Possible values
are "none", "bti" and "standard".

When the provided value is "bti" o "standard" the bti pass is run.  By
defaut the pass is off.

Regressioned and bootstraped on arm-linux-gnu aarch64-linux-gnu.

Best Regards

  Andrea

[1] <https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension>
From aec6bfd6d65fc4b5675dcc89417bc2612dd719cd Mon Sep 17 00:00:00 2001
From: Andrea Corallo <andrea.corallo@arm.com>
Date: Wed, 8 Sep 2021 18:10:15 +0200
Subject: [PATCH 2/2] arm: implement -mbranch-protection command line option

gcc/ChangeLog

2021-09-15  Andrea Corallo  <andrea.corallo@arm.com>

	* doc/invoke.texi (-mbranch-protection): Document.

	* config/arm/arm.opt (-mbranch-protection): Add option.

	* config/arm/arm.h (TARGET_HAVE_PACBTI): New macro.

	* config/arm/arm.c (arm_parse_branch_protection): New function.
	(arm_configure_build_target): Invoke 'arm_parse_branch_protection'
	+ verify 'arm_enable_bti'.

	* config/arm/arm.c (arm_file_start): Set 'Tag_BTI_extension'
	'Tag_BTI_use' attribute.
---
 gcc/config/arm/arm.c   | 30 +++++++++++++++++++++++++++++-
 gcc/config/arm/arm.h   |  4 ++++
 gcc/config/arm/arm.opt |  7 +++++++
 gcc/doc/invoke.texi    |  8 ++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)
  

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b62db21a734..75b9b03d680 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3172,6 +3172,25 @@  static sbitmap isa_all_fpubits_internal;
 static sbitmap isa_all_fpbits;
 static sbitmap isa_quirkbits;
 
+static void
+arm_parse_branch_protection (const char *str)
+{
+  if (!strcmp(str, "none"))
+    {
+      arm_enable_bti = false;
+      return;
+    }
+
+  if (!strcmp(str, "bti")
+      || !strcmp(str, "standard"))
+    {
+      arm_enable_bti = true;
+      return;
+    }
+
+  error ("invalid -mbranch-protection option: %qs", str);
+}
+
 /* Configure a build target TARGET from the user-specified options OPTS and
    OPTS_SET.  If WARN_COMPATIBLE, emit a diagnostic if both the CPU and
    architecture have been specified, but the two are not identical.  */
@@ -3200,6 +3219,9 @@  arm_configure_build_target (struct arm_build_target *target,
       arch_opts = strchr (opts->x_arm_arch_string, '+');
     }
 
+  if (opts->x_arm_branch_protection_string)
+    arm_parse_branch_protection (opts->x_arm_branch_protection_string);
+
   if (opts->x_arm_cpu_string)
     {
       arm_selected_cpu = arm_parse_cpu_option_name (all_cores, "-mcpu",
@@ -28266,6 +28288,12 @@  arm_file_start (void)
 	arm_emit_eabi_attribute ("Tag_ABI_FP_16bit_format", 38,
 			     (int) arm_fp16_format);
 
+      if (arm_enable_bti)
+	{
+	  arm_emit_eabi_attribute ("Tag_BTI_extension", 52, 1);
+	  arm_emit_eabi_attribute ("Tag_BTI_use", 52, 1);
+	}
+
       if (arm_lang_output_object_attributes_hook)
 	arm_lang_output_object_attributes_hook();
     }
@@ -32802,7 +32830,7 @@  arm_fusion_enabled_p (tune_params::fuse_ops op)
 bool
 aarch_bti_enabled (void)
 {
-  return false; // FIXME
+  return arm_enable_bti;
 }
 
 /* Check if INSN is a BTI J insn.  */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 015299c1534..31b685f081d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -628,6 +628,10 @@  extern const int arm_arch_cde_coproc_bits[];
    LOB (low overhead branch features) extension instructions.  */
 #define TARGET_HAVE_LOB (arm_arch8_1m_main)
 
+/* Nonzero if this chip provides Armv8.1-M Mainline
+   PAC-BTI extension instructions.  */
+#define TARGET_HAVE_PACBTI (arm_arch8_1m_main)
+
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases,
    the value is constrained to be within the bounds of the declared
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index af478a946b2..782d1c23484 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -54,6 +54,9 @@  Enum(arm_abi_type) String(iwmmxt) Value(ARM_ABI_IWMMXT)
 EnumValue
 Enum(arm_abi_type) String(aapcs-linux) Value(ARM_ABI_AAPCS_LINUX)
 
+TargetVariable
+bool arm_enable_bti = false
+
 mabort-on-noreturn
 Target Mask(ABORT_NORETURN)
 Generate a call to abort if a noreturn function returns.
@@ -300,6 +303,10 @@  mbranch-cost=
 Target RejectNegative Joined UInteger Var(arm_branch_cost) Init(-1)
 Cost to assume for a branch insn.
 
+mbranch-protection=
+Target RejectNegative Joined Var(arm_branch_protection_string) Save
+Use branch-protection features.
+
 mgeneral-regs-only
 Target RejectNegative Mask(GENERAL_REGS_ONLY) Save
 Generate code which uses the core registers only (r0-r14).
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d8a6b0b60c9..90f132252f1 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -786,6 +786,7 @@  Objective-C and Objective-C++ Dialects}.
 -mfp16-format=@var{name}
 -mthumb-interwork  -mno-thumb-interwork @gol
 -mcpu=@var{name}  -march=@var{name}  -mfpu=@var{name}  @gol
+-mbranch-protection=@var{none}|@var{standard}@var{bti} @gol
 -mtune=@var{name}  -mprint-tune-info @gol
 -mstructure-size-boundary=@var{n} @gol
 -mabort-on-noreturn @gol
@@ -20544,6 +20545,13 @@  long_calls_off} directive.  Note these switches have no effect on how
 the compiler generates code to handle function calls via function
 pointers.
 
+@item -mbranch-protection=@var{none}|@var{standard}|@var{bti}
+@opindex mbranch-protection
+Select the branch protection features to use.
+@samp{none} is the default and turns off all types of branch protection.
+@samp{standard} turns on all types of branch protection features.
+@samp{bti} turns on branch target identification mechanism.
+
 @item -msingle-pic-base
 @opindex msingle-pic-base
 Treat the register used for PIC addressing as read-only, rather than