aarch64: Fix missing BTI instruction in trampolines
If two functions require trampolines, and the first has BTI enabled while the second doesn't, the generated template will be lacking a BTI instruction. This patch fixes this by always adding a BTI instruction, which is safe as BTI instructions are ignored on unsupported architecture versions. 2020-07-01 Omar Tahir <omar.tahir@arm.com> gcc/ * config/aarch64/aarch64.c (aarch64_asm_trampoline_template): Always generate a BTI instruction. gcc/testsuite/ * gcc.target/aarch64/bti-4.c: New test.
This commit is contained in:
parent
553c657206
commit
be7c41a556
2 changed files with 68 additions and 22 deletions
|
@ -10833,40 +10833,26 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
|
|||
return get_hard_reg_initial_val (Pmode, LR_REGNUM);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
aarch64_asm_trampoline_template (FILE *f)
|
||||
{
|
||||
int offset1 = 16;
|
||||
int offset2 = 20;
|
||||
|
||||
if (aarch64_bti_enabled ())
|
||||
{
|
||||
asm_fprintf (f, "\thint\t34 // bti c\n");
|
||||
offset1 -= 4;
|
||||
offset2 -= 4;
|
||||
}
|
||||
/* Even if the current function doesn't have branch protection, some
|
||||
later function might, so since this template is only generated once
|
||||
we have to add a BTI just in case. */
|
||||
asm_fprintf (f, "\thint\t34 // bti c\n");
|
||||
|
||||
if (TARGET_ILP32)
|
||||
{
|
||||
asm_fprintf (f, "\tldr\tw%d, .+%d\n", IP1_REGNUM - R0_REGNUM, offset1);
|
||||
asm_fprintf (f, "\tldr\tw%d, .+%d\n", STATIC_CHAIN_REGNUM - R0_REGNUM,
|
||||
offset1);
|
||||
asm_fprintf (f, "\tldr\tw%d, .+12\n", IP1_REGNUM - R0_REGNUM);
|
||||
asm_fprintf (f, "\tldr\tw%d, .+12\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm_fprintf (f, "\tldr\t%s, .+%d\n", reg_names [IP1_REGNUM], offset1);
|
||||
asm_fprintf (f, "\tldr\t%s, .+%d\n", reg_names [STATIC_CHAIN_REGNUM],
|
||||
offset2);
|
||||
asm_fprintf (f, "\tldr\t%s, .+12\n", reg_names [IP1_REGNUM]);
|
||||
asm_fprintf (f, "\tldr\t%s, .+16\n", reg_names [STATIC_CHAIN_REGNUM]);
|
||||
}
|
||||
asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]);
|
||||
|
||||
/* The trampoline needs an extra padding instruction. In case if BTI is
|
||||
enabled the padding instruction is replaced by the BTI instruction at
|
||||
the beginning. */
|
||||
if (!aarch64_bti_enabled ())
|
||||
assemble_aligned_integer (4, const0_rtx);
|
||||
|
||||
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
||||
assemble_aligned_integer (POINTER_BYTES, const0_rtx);
|
||||
}
|
||||
|
|
60
gcc/testsuite/gcc.target/aarch64/bti-4.c
Normal file
60
gcc/testsuite/gcc.target/aarch64/bti-4.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* { dg-do compile } */
|
||||
/* If configured with --enable-standard-branch-protection, disable it. */
|
||||
/* { dg-additional-options "-mbranch-protection=none" { target { default_branch_protection } } } */
|
||||
|
||||
void f1 (void *);
|
||||
void f2 (void *);
|
||||
void f3 (void *, void (*)(void *));
|
||||
|
||||
int
|
||||
retbr_trampolines (void *a, int b)
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
f1 (a);
|
||||
return 1;
|
||||
}
|
||||
if (b)
|
||||
{
|
||||
/* Suppress "ISO C forbids nested functions" warning. */
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wpedantic\"")
|
||||
void retbr_tramp_internal (void *c)
|
||||
{
|
||||
_Pragma("GCC diagnostic pop")
|
||||
if (c == a)
|
||||
f2 (c);
|
||||
}
|
||||
f3 (a, retbr_tramp_internal);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((target("branch-protection=bti,arch=armv8.3-a")))
|
||||
int
|
||||
retbr_trampolines2 (void *a, int b)
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
f1 (a);
|
||||
return 1;
|
||||
}
|
||||
if (b)
|
||||
{
|
||||
/* Suppress "ISO C forbids nested functions" warning. */
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wpedantic\"")
|
||||
__attribute__((target("branch-protection=bti,arch=armv8.3-a")))
|
||||
void retbr_tramp_internal2 (void *c)
|
||||
{
|
||||
_Pragma("GCC diagnostic pop")
|
||||
if (c == a)
|
||||
f2 (c);
|
||||
}
|
||||
f3 (a, retbr_tramp_internal2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Trampoline should have BTI C. */
|
||||
/* { dg-final { scan-assembler "\.LTRAMP0:\n\thint\t34" } } */
|
Loading…
Add table
Reference in a new issue