public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Andrea Corallo <akrl@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc(refs/vendors/ARM/heads/arm-12-m-pacbti)] [PATCH 12/15] arm: implement bti injection
Date: Fri, 10 Mar 2023 16:21:33 +0000 (GMT)	[thread overview]
Message-ID: <20230310162133.984123858023@sourceware.org> (raw)

https://gcc.gnu.org/g:a93bf01521c09d99a21086ece64e74345069fa03

commit a93bf01521c09d99a21086ece64e74345069fa03
Author: Andrea Corallo <andrea.corallo@arm.com>
Date:   Thu Apr 7 11:51:56 2022 +0200

    [PATCH 12/15] arm: implement bti injection
    
    Hi all,
    
    this patch enables Branch Target Identification Armv8.1-M Mechanism
    [1].
    
    This is achieved by using the bti pass made common with Aarch64.
    
    The pass iterates through the instructions and adds the necessary BTI
    instructions at the beginning of every function and at every landing
    pads targeted by indirect jumps.
    
    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>
    
    gcc/ChangeLog
    
    2022-04-07  Andrea Corallo  <andrea.corallo@arm.com>
    
            * config.gcc (arm*-*-*): Add 'aarch-bti-insert.o' object.
            * config/arm/arm-protos.h: Update.
            * config/arm/aarch-common-protos.h: Declare
            'aarch_bti_arch_check'.
            * config/arm/arm.cc (aarch_bti_enabled) Update.
            (aarch_bti_j_insn_p, aarch_pac_insn_p, aarch_gen_bti_c)
            (aarch_gen_bti_j, aarch_bti_arch_check): New functions.
            * config/arm/arm.md (bti_nop): New insn.
            * config/arm/t-arm (PASSES_EXTRA): Add 'arm-passes.def'.
            (aarch-bti-insert.o): New target.
            * config/arm/unspecs.md (VUNSPEC_BTI_NOP): New unspec.
            * config/arm/aarch-bti-insert.cc (rest_of_insert_bti): Verify arch
            compatibility.
            (gate): Make use of 'aarch_bti_arch_check'.
            * config/arm/arm-passes.def: New file.
            * config/aarch64/aarch64.cc (aarch_bti_arch_check): New function.
    
    gcc/testsuite/ChangeLog
    
    2022-04-07  Andrea Corallo  <andrea.corallo@arm.com>
    
            * gcc.target/arm/bti-1.c: New testcase.
            * gcc.target/arm/bti-2.c: Likewise.

Diff:
---
 gcc/config.gcc                       |  2 +-
 gcc/config/aarch64/aarch64.cc        |  4 +++
 gcc/config/arm/aarch-bti-insert.cc   |  7 ++++-
 gcc/config/arm/aarch-common-protos.h |  1 +
 gcc/config/arm/arm-passes.def        | 21 +++++++++++++
 gcc/config/arm/arm-protos.h          |  2 ++
 gcc/config/arm/arm.cc                | 60 ++++++++++++++++++++++++++++++++++--
 gcc/config/arm/arm.md                |  7 +++++
 gcc/config/arm/t-arm                 | 10 ++++++
 gcc/config/arm/unspecs.md            |  1 +
 gcc/testsuite/gcc.target/arm/bti-1.c | 12 ++++++++
 gcc/testsuite/gcc.target/arm/bti-2.c | 58 ++++++++++++++++++++++++++++++++++
 12 files changed, 181 insertions(+), 4 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index c1d51083626..4135169d6f0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -353,7 +353,7 @@ arc*-*-*)
 	;;
 arm*-*-*)
 	cpu_type=arm
-	extra_objs="arm-builtins.o arm-mve-builtins.o aarch-common.o"
+	extra_objs="arm-builtins.o arm-mve-builtins.o aarch-common.o aarch-bti-insert.o"
 	extra_headers="mmintrin.h arm_neon.h arm_acle.h arm_fp16.h arm_cmse.h arm_bf16.h arm_mve_types.h arm_mve.h arm_cde.h"
 	target_type_format_char='%'
 	c_target_objs="arm-c.o"
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 375fd7a5f00..25eb48022eb 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8582,6 +8582,10 @@ aarch64_return_address_signing_enabled (void)
 	      && known_ge (cfun->machine->frame.reg_offset[LR_REGNUM], 0)));
 }
 
+/* Only used by the arm backend.  */
+void aarch_bti_arch_check (void)
+{}
+
 /* Return TRUE if Branch Target Identification Mechanism is enabled.  */
 bool
 aarch_bti_enabled (void)
diff --git a/gcc/config/arm/aarch-bti-insert.cc b/gcc/config/arm/aarch-bti-insert.cc
index 2d1d2e334a9..30d5bfcb77b 100644
--- a/gcc/config/arm/aarch-bti-insert.cc
+++ b/gcc/config/arm/aarch-bti-insert.cc
@@ -190,7 +190,12 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return aarch_bti_enabled ();
+      if (aarch_bti_enabled ())
+        {
+          aarch_bti_arch_check ();
+          return true;
+        }
+      return false;
     }
 
   virtual unsigned int execute (function *)
diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h
index 374982752ad..f795730a59c 100644
--- a/gcc/config/arm/aarch-common-protos.h
+++ b/gcc/config/arm/aarch-common-protos.h
@@ -42,6 +42,7 @@ extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
 extern int arm_no_early_mul_dep (rtx, rtx);
 extern int arm_no_early_store_addr_dep (rtx, rtx);
 extern bool arm_rtx_shift_left_p (rtx);
+extern void aarch_bti_arch_check (void);
 extern bool aarch_bti_enabled (void);
 extern bool aarch_bti_j_insn_p (rtx_insn *);
 extern bool aarch_pac_insn_p (rtx);
diff --git a/gcc/config/arm/arm-passes.def b/gcc/config/arm/arm-passes.def
new file mode 100644
index 00000000000..71d6b563640
--- /dev/null
+++ b/gcc/config/arm/arm-passes.def
@@ -0,0 +1,21 @@
+/* Arm-specific passes declarations.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   Contributed by Arm Ltd.
+
+   This file is part of GCC.
+
+   GCC 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, or (at your option)
+   any later version.
+
+   GCC 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/>.  */
+
+INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_bti);
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 9ee1edbe347..d43e42811cb 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -24,6 +24,8 @@
 
 #include "sbitmap.h"
 
+rtl_opt_pass *make_pass_insert_bti (gcc::context *ctxt);
+
 extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
 extern int use_return_insn (int, rtx);
 extern bool use_simple_return_p (void);
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index d608d566b5f..be2893ea6ff 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -33012,13 +33012,69 @@ arm_current_function_pac_enabled_p (void)
               && !crtl->is_leaf));
 }
 
+/* Raise an error if the current target arch is not bti compatible.  */
+void aarch_bti_arch_check (void)
+{
+  if (!arm_arch8m_main)
+    error ("This architecture does not support branch protection instructions");
+}
+
 /* Return TRUE if Branch Target Identification Mechanism is enabled.  */
-static bool
-aarch_bti_enabled ()
+bool
+aarch_bti_enabled (void)
+{
+  return aarch_enable_bti != 0;
+}
+
+/* Check if INSN is a BTI J insn.  */
+bool
+aarch_bti_j_insn_p (rtx_insn *insn)
+{
+  if (!insn || !INSN_P (insn))
+    return false;
+
+  rtx pat = PATTERN (insn);
+  return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == VUNSPEC_BTI_NOP;
+}
+
+/* Check if X (or any sub-rtx of X) is a PACIASP/PACIBSP instruction.  */
+bool
+aarch_pac_insn_p (rtx x)
 {
+  if (!x || !INSN_P (x))
+    return false;
+
+  rtx pat = PATTERN (x);
+
+  if (GET_CODE (pat) == SET)
+    {
+      rtx tmp = XEXP (pat, 1);
+      if (tmp
+	  && ((GET_CODE (tmp) == UNSPEC
+               && XINT (tmp, 1) == UNSPEC_PAC_NOP)
+              || (GET_CODE (tmp) == UNSPEC_VOLATILE
+                  && XINT (tmp, 1) == VUNSPEC_PACBTI_NOP)))
+	return true;
+    }
+
   return false;
 }
 
+ /* Target specific mapping for aarch_gen_bti_c and aarch_gen_bti_j.
+    For Arm, both of these map to a simple BTI instruction.  */
+
+rtx
+aarch_gen_bti_c (void)
+{
+  return gen_bti_nop ();
+}
+
+rtx
+aarch_gen_bti_j (void)
+{
+  return gen_bti_nop ();
+}
+
 /* Implement TARGET_SCHED_CAN_SPECULATE_INSN.  Return true if INSN can be
    scheduled for speculative execution.  Reject the long-running division
    and square-root instructions.  */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 21aaa765a3e..92b86c5d49d 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12913,6 +12913,13 @@
   "aut\t%|ip, %|lr, %|sp"
   [(set_attr "conds" "unconditional")])
 
+(define_insn "bti_nop"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_BTI_NOP)]
+  "arm_arch8m_main"
+  "bti"
+  [(set_attr "conds" "unconditional")
+   (set_attr "type" "nop")])
+
 ;; Vector bits common to IWMMXT, Neon and MVE
 (include "vec-common.md")
 ;; Load the Intel Wireless Multimedia Extension patterns
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 041cc6ec045..683342cb528 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -175,3 +175,13 @@ arm-d.o: $(srcdir)/config/arm/arm-d.cc
 arm-common.o: arm-cpu-cdata.h
 
 driver-arm.o: arm-native.h
+
+PASSES_EXTRA += $(srcdir)/config/arm/arm-passes.def
+
+aarch-bti-insert.o: $(srcdir)/config/arm/aarch-bti-insert.cc \
+    $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(REGS_H) insn-config.h $(RTL_BASE_H) \
+    dominance.h cfg.h cfganal.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(RECOG_H) \
+    output.h hash-map.h $(DF_H) $(OBSTACK_H) $(TARGET_H) $(RTL_H) \
+    $(CONTEXT_H) $(TREE_PASS_H) regrename.h
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+		$(srcdir)/config/arm/aarch-bti-insert.cc
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 370f0b12da1..93447a8ce9d 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -257,6 +257,7 @@
 			; instruction.
   VUNSPEC_PACBTI_NOP	; Represents PAC signing LR + valid landing pad
   VUNSPEC_AUT_NOP	; Represents PAC verifying LR
+  VUNSPEC_BTI_NOP	; Represent BTI
 ])
 
 ;; Enumerators for NEON unspecs.
diff --git a/gcc/testsuite/gcc.target/arm/bti-1.c b/gcc/testsuite/gcc.target/arm/bti-1.c
new file mode 100644
index 00000000000..79dd8010d2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bti-1.c
@@ -0,0 +1,12 @@
+/* Check that GCC does bti instruction.  */
+/* { dg-do compile } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */
+/* { dg-options "-march=armv8.1-m.main -mthumb -mfloat-abi=softfp -mbranch-protection=bti --save-temps" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler "bti" } } */
diff --git a/gcc/testsuite/gcc.target/arm/bti-2.c b/gcc/testsuite/gcc.target/arm/bti-2.c
new file mode 100644
index 00000000000..33910563849
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bti-2.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* -Os to create jump table.  */
+/* { dg-options "-Os" } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */
+/* { dg-options "-march=armv8.1-m.main -mthumb -mfloat-abi=softfp -mbranch-protection=bti --save-temps" } */
+
+extern int f1 (void);
+extern int f2 (void);
+extern int f3 (void);
+extern int f4 (void);
+extern int f5 (void);
+extern int f6 (void);
+extern int f7 (void);
+extern int f8 (void);
+extern int f9 (void);
+extern int f10 (void);
+
+int (*ptr) (void);
+
+int
+f_jump_table (int y, int n)
+{
+  int i;
+  for (i = 0; i < n ;i ++)
+  {
+    switch (y)
+      {
+      case 0 : ptr = f1; break;
+      case 1 : ptr = f2; break;
+      case 2 : ptr = f3; break;
+      case 3 : ptr = f4; break;
+      case 4 : ptr = f5; break;
+      case 5 : ptr = f6; break;
+      case 6 : ptr = f7; break;
+      case 7 : ptr = f8; break;
+      case 8 : ptr = f9; break;
+      case 9 : ptr = f10; break;
+      default: break;
+      }
+    y += ptr ();
+  }
+  return (y == 0)? y+1:4;
+}
+
+int
+f_label_address ()
+{
+  static void * addr = &&lab1;
+  goto *addr;
+lab1:
+  addr = &&lab2;
+  return 1;
+lab2:
+  addr = &&lab1;
+  return 2;
+}
+
+/* { dg-final { scan-assembler-times "bti" 15 } } */

             reply	other threads:[~2023-03-10 16:21 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-10 16:21 Andrea Corallo [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-08-12 16:31 Andrea Corallo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230310162133.984123858023@sourceware.org \
    --to=akrl@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).