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);
}
--- /dev/null
+/* { 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" } } */