Commit f7e4641a by Szabolcs Nagy

aarch64: ensure bti c is emitted at function start [PR94697]

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:

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

gcc/testsuite/ChangeLog:

	PR target/94697
	* gcc.target/aarch64/pr94697.c: New test.
parent 857d1fa3
2020-04-23 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR target/94697
* config/aarch64/aarch64-bti-insert.c (rest_of_insert_bti): Swap
bti c and bti j handling.
2020-04-23 Andrew Stubbs <ams@codesourcery.com>
Thomas Schwinge <thomas@codesourcery.com>
......
......@@ -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;
}
......
2020-04-23 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR target/94697
* gcc.target/aarch64/pr94697.c: New test.
2020-04-23 Felix Yang <felix.yang@huawei.com>
PR target/94678
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment