Static tramp v5 (#624)
[platform/upstream/libffi.git] / src / x86 / unix64.S
index 89d7db1..ca6fe0c 100644 (file)
@@ -456,6 +456,81 @@ L(sse_entry2):
 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__