L(UW17):
ENDF(C(ffi_go_closure_unix64))
+#if defined(FFI_EXEC_STATIC_TRAMP)
+ .balign 8
+ .globl C(ffi_closure_unix64_sse_alt)
+ FFI_HIDDEN(C(ffi_closure_unix64_sse_alt))
+
+C(ffi_closure_unix64_sse_alt):
+ /* See the comments above trampoline_code_table. */
+ _CET_ENDBR
+ movq 8(%rsp), %r10 /* Load closure in r10 */
+ addq $16, %rsp /* Restore the stack */
+ jmp C(ffi_closure_unix64_sse)
+ENDF(C(ffi_closure_unix64_sse_alt))
+
+ .balign 8
+ .globl C(ffi_closure_unix64_alt)
+ FFI_HIDDEN(C(ffi_closure_unix64_alt))
+
+C(ffi_closure_unix64_alt):
+ /* See the comments above trampoline_code_table. */
+ _CET_ENDBR
+ movq 8(%rsp), %r10 /* Load closure in r10 */
+ addq $16, %rsp /* Restore the stack */
+ jmp C(ffi_closure_unix64)
+ ENDF(C(ffi_closure_unix64_alt))
+
+/*
+ * Below is the definition of the trampoline code table. Each element in
+ * the code table is a trampoline.
+ *
+ * Because we jump to the trampoline, we place a _CET_ENDBR at the
+ * beginning of the trampoline to mark it as a valid branch target. This is
+ * part of the the Intel CET (Control Flow Enforcement Technology).
+ */
+/*
+ * The trampoline uses register r10. It saves the original value of r10 on
+ * the stack.
+ *
+ * The trampoline has two parameters - target code to jump to and data for
+ * the target code. The trampoline extracts the parameters from its parameter
+ * block (see tramp_table_map()). The trampoline saves the data address on
+ * the stack. Finally, it jumps to the target code.
+ *
+ * The target code can choose to:
+ *
+ * - restore the value of r10
+ * - load the data address in a register
+ * - restore the stack pointer to what it was when the trampoline was invoked.
+ */
+#ifdef ENDBR_PRESENT
+#define X86_DATA_OFFSET 4077
+#define X86_CODE_OFFSET 4073
+#else
+#define X86_DATA_OFFSET 4081
+#define X86_CODE_OFFSET 4077
+#endif
+
+ .align UNIX64_TRAMP_MAP_SIZE
+ .globl trampoline_code_table
+ FFI_HIDDEN(C(trampoline_code_table))
+
+C(trampoline_code_table):
+ .rept UNIX64_TRAMP_MAP_SIZE / UNIX64_TRAMP_SIZE
+ _CET_ENDBR
+ subq $16, %rsp /* Make space on the stack */
+ movq %r10, (%rsp) /* Save %r10 on stack */
+ movq X86_DATA_OFFSET(%rip), %r10 /* Copy data into %r10 */
+ movq %r10, 8(%rsp) /* Save data on stack */
+ movq X86_CODE_OFFSET(%rip), %r10 /* Copy code into %r10 */
+ jmp *%r10 /* Jump to code */
+ .align 8
+ .endr
+ENDF(C(trampoline_code_table))
+ .align UNIX64_TRAMP_MAP_SIZE
+#endif /* FFI_EXEC_STATIC_TRAMP */
+
/* Sadly, OSX cctools-as doesn't understand .cfi directives at all. */
#ifdef __APPLE__