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