The bti pass currently first emits bti c at function start
if there is no paciasp (which also acts as indirect call
landing pad), then bti j is emitted at jump labels, however
if there is a label right before paciasp then the function
start can end up like

  foo:
  label:
    bti j
    paciasp
    ...

This patch is a minimal fix that just moves the bti c handling
after the bti j handling so we end up with

  foo:
    bti c
  label:
    bti j
    paciasp
    ...

This could be improved by emitting bti jc in this case, or by
detecting that the label is not in fact an indirect jump target
and then this situation would be much less common.

Needs to be backported to gcc-9 branch.

gcc/ChangeLog:

2020-04-XX  Szabolcs Nagy  <szabolcs.n...@arm.com>

        PR target/94697
        * config/aarch64/aarch64-bti-insert.c (rest_of_insert_bti): Swap
        bti c and bti j handling.

gcc/testsuite/ChangeLog:

2020-04-XX  Szabolcs Nagy  <szabolcs.n...@arm.com>

        PR target/94697
        * gcc.target/aarch64/pr94697.c: New test.
---
 gcc/config/aarch64/aarch64-bti-insert.c    | 32 +++++++++++-----------
 gcc/testsuite/gcc.target/aarch64/pr94697.c | 19 +++++++++++++
 2 files changed, 35 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr94697.c

diff --git a/gcc/config/aarch64/aarch64-bti-insert.c 
b/gcc/config/aarch64/aarch64-bti-insert.c
index 295d18acab8..aa091c308f6 100644
--- a/gcc/config/aarch64/aarch64-bti-insert.c
+++ b/gcc/config/aarch64/aarch64-bti-insert.c
@@ -132,22 +132,6 @@ rest_of_insert_bti (void)
   rtx_insn *insn;
   basic_block bb;
 
-  /* Since a Branch Target Exception can only be triggered by an indirect call,
-     we exempt function that are only called directly.  We also exempt
-     functions that are already protected by Return Address Signing (PACIASP/
-     PACIBSP).  For all other cases insert a BTI C at the beginning of the
-     function.  */
-  if (!cgraph_node::get (cfun->decl)->only_called_directly_p ())
-    {
-      bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
-      insn = BB_HEAD (bb);
-      if (!aarch64_pac_insn_p (get_first_nonnote_insn ()))
-       {
-         bti_insn = gen_bti_c ();
-         emit_insn_before (bti_insn, insn);
-       }
-    }
-
   bb = 0;
   FOR_EACH_BB_FN (bb, cfun)
     {
@@ -203,6 +187,22 @@ rest_of_insert_bti (void)
        }
     }
 
+  /* Since a Branch Target Exception can only be triggered by an indirect call,
+     we exempt function that are only called directly.  We also exempt
+     functions that are already protected by Return Address Signing (PACIASP/
+     PACIBSP).  For all other cases insert a BTI C at the beginning of the
+     function.  */
+  if (!cgraph_node::get (cfun->decl)->only_called_directly_p ())
+    {
+      bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+      insn = BB_HEAD (bb);
+      if (!aarch64_pac_insn_p (get_first_nonnote_insn ()))
+       {
+         bti_insn = gen_bti_c ();
+         emit_insn_before (bti_insn, insn);
+       }
+    }
+
   timevar_pop (TV_MACH_DEP);
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/pr94697.c 
b/gcc/testsuite/gcc.target/aarch64/pr94697.c
new file mode 100644
index 00000000000..e6069d22ece
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr94697.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=standard" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void bar (int *);
+void *addr;
+
+/*
+** foo:
+**     hint    (25|34|38) // (paciasp|bti c|bti jc)
+**     ...
+*/
+int foo (int x)
+{
+label:
+  addr = &&label;
+  bar (&x);
+  return x;
+}
-- 
2.17.1


Reply via email to