Add static trampoline support for s390 (#862)
authorEddy S. <fneddy@users.noreply.github.com>
Sat, 16 Nov 2024 12:03:24 +0000 (13:03 +0100)
committerGitHub <noreply@github.com>
Sat, 16 Nov 2024 12:03:24 +0000 (07:03 -0500)
* added static trampoline support for s390

* enable static tramp only for  s390x 64bit

configure.ac
src/s390/ffi.c
src/s390/internal.h
src/s390/sysv.S

index b5a7a49f1eefb2b8cd84fddb09a8516c346e16fa..b4199ab154179517232d87424795540b11326168 100644 (file)
@@ -382,7 +382,7 @@ case "$target" in
                    [Define this if you want statically defined trampolines])
        fi
      ;;
-     *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* | loongarch*-*-linux-*)
+     *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* | loongarch*-*-linux-* | s390x*-linux-*)
        AC_DEFINE(FFI_EXEC_STATIC_TRAMP, 1,
                  [Define this if you want statically defined trampolines])
      ;;
index 4035b6e366e6655ea263dfcf8df6a678455d1293..b197cd5fa609ca962802fbb4dcb663f16ff9c78a 100644 (file)
@@ -32,6 +32,7 @@
 #include <ffi_common.h>
 #include <stdint.h>
 #include "internal.h"
+#include <tramp.h>
 
 /*====================== End of Includes =============================*/
 
@@ -720,16 +721,30 @@ ffi_prep_closure_loc (ffi_closure *closure,
 #endif
     0x07f1                     /* br %r1 */
   };
-
+  void (*dest)(void);
   unsigned long *tramp = (unsigned long *)&closure->tramp;
 
   if (cif->abi != FFI_SYSV)
     return FFI_BAD_ABI;
 
+
+#if defined(FFI_EXEC_STATIC_TRAMP)
+  if (ffi_tramp_is_present(closure))
+    {
+      /* Initialize the static trampoline's parameters. */
+      dest = ffi_closure_SYSV;
+      ffi_tramp_set_parms (closure->ftramp, dest, closure);
+      goto out;
+    }
+#endif
+
   memcpy (tramp, template, sizeof(template));
   tramp[2] = (unsigned long)codeloc;
   tramp[3] = (unsigned long)&ffi_closure_SYSV;
 
+#if defined(FFI_EXEC_STATIC_TRAMP)
+out:
+#endif
   closure->cif = cif;
   closure->fun = fun;
   closure->user_data = user_data;
@@ -754,3 +769,15 @@ ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
 
   return FFI_OK;
 }
+
+#if defined(FFI_EXEC_STATIC_TRAMP)
+void *
+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
+{
+  extern void *trampoline_code_table;
+
+  *tramp_size = FFI390_TRAMP_SIZE;
+  *map_size = FFI390_TRAMP_MAP_SIZE;
+  return &trampoline_code_table;
+}
+#endif
\ No newline at end of file
index b8755786f9e4f5e0d9a2d9d52ffb40a22aaae5d0..eba8e86d439cf6b654029590be19e6993bcc3541 100644 (file)
@@ -9,3 +9,14 @@
 #define FFI390_RET_IN_MEM      8
 
 #define FFI390_RET_STRUCT      (FFI390_RET_VOID | FFI390_RET_IN_MEM)
+
+
+#if defined(FFI_EXEC_STATIC_TRAMP)
+/*
+ * For the trampoline code table mapping, a mapping size of 4K is chosen.
+ */
+#define FFI390_TRAMP_MAP_SHIFT 12
+#define FFI390_TRAMP_MAP_SIZE  (1 << FFI390_TRAMP_MAP_SHIFT)
+#define FFI390_TRAMP_SIZE      16
+
+#endif
index c4b5006aed07454aba41870f4bc2bb1bac65a88e..d603218e6e200d82c71c2a57f108d9f9525d5f84 100644 (file)
@@ -28,6 +28,7 @@
 #define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
+#include "internal.h"
 
        .text
 
@@ -318,6 +319,43 @@ ffi_closure_SYSV:
        br      %r14
        .cfi_endproc
        .size    ffi_closure_SYSV,.-ffi_closure_SYSV
+
+
+#if defined(FFI_EXEC_STATIC_TRAMP)
+/*
+ * Below is the definition of the trampoline code table. Each element in
+ * the code table is a trampoline.
+ */
+/*
+ * The trampoline uses the volatile register r0 and r1. As the registers are
+ * marked volatile in the ABI, the original values are not saved.
+ *
+ * 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 in r0.
+ * Finally, it jumps to the target code.
+ */
+
+       .align  FFI390_TRAMP_MAP_SIZE
+trampoline_code_table:
+       .rept   FFI390_TRAMP_MAP_SIZE / FFI390_TRAMP_SIZE
+       basr %r1,0              # load next instruction address to r1
+       lmg %r0,%r1,4094(%r1)   # load parameter block
+                                                       #               r0 -> data
+                                                       #               r1 -> code
+       br %r1                  # jump to r1/code
+       .balign 8
+       .endr
+
+       .globl trampoline_code_table
+       FFI_HIDDEN(trampoline_code_table)
+#ifdef __ELF__
+       .type   trampoline_code_table, @function
+       .size   trampoline_code_table,.- trampoline_code_table
+#endif
+       .align  FFI390_TRAMP_MAP_SIZE
+#endif /* FFI_EXEC_STATIC_TRAMP */
+
 #endif /* !s390x */
 
 #if defined __ELF__ && defined __linux__