[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])
;;
#include <ffi_common.h>
#include <stdint.h>
#include "internal.h"
+#include <tramp.h>
/*====================== End of Includes =============================*/
#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;
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
#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
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
+#include "internal.h"
.text
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__