From: Omar Tahir Date: Wed, 1 Jul 2020 20:56:16 +0000 (+0100) Subject: aarch64: Fix missing BTI instruction in trampolines X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=be7c41a556464680b17a2c3d5d099ec56a2c223e;p=gcc.git 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 gcc/ * config/aarch64/aarch64.c (aarch64_asm_trampoline_template): Always generate a BTI instruction. gcc/testsuite/ * gcc.target/aarch64/bti-4.c: New test. --- diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 57988f9330b..24c31c2d02c 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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); } diff --git a/gcc/testsuite/gcc.target/aarch64/bti-4.c b/gcc/testsuite/gcc.target/aarch64/bti-4.c new file mode 100644 index 00000000000..28495a5c199 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bti-4.c @@ -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" } } */