Since nested function isn't only called directly, there is ENDBR32 at
function entry and we need to skip it for direct jump in trampoline.
Tested on Linux/x86-64 CET machine with and without -m32.
gcc/
PR target/93656
* config/i386/i386.c (ix86_trampoline_init): Skip ENDBR32 at
nested function entry.
gcc/testsuite/
PR target/93656
* gcc.target/i386/pr93656.c: New test.
---
gcc/config/i386/i386.c | 7 ++++++-
gcc/testsuite/gcc.target/i386/pr93656.c | 4 ++++
2 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr93656.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 44bc0e0176a..dbcae244acb 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16839,9 +16839,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx
chain_value)
the stack, we need to skip the first insn which pushes the
(call-saved) register static chain; this push is 1 byte. */
offset += 5;
+ int skip = MEM_P (chain) ? 1 : 0;
+ /* Since nested function isn't only called directly, there is
+ ENDBR32 at function entry and we need to skip it. */
+ if (need_endbr)
+ skip += 4;
disp = expand_binop (SImode, sub_optab, fnaddr,
plus_constant (Pmode, XEXP (m_tramp, 0),
- offset - (MEM_P (chain) ? 1 : 0)),
+ offset - skip),
NULL_RTX, 1, OPTAB_DIRECT);
emit_move_insn (mem, disp);
}
diff --git a/gcc/testsuite/gcc.target/i386/pr93656.c
b/gcc/testsuite/gcc.target/i386/pr93656.c
new file mode 100644
index 00000000000..f0ac8c8edaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr93656.c
@@ -0,0 +1,4 @@
+/* { dg-do run { target { ia32 && cet } } } */
+/* { dg-options "-O2 -fcf-protection" } */
+
+#include "pr67770.c"
--
2.24.1