summaryrefslogtreecommitdiff
path: root/src/loongarch64/ffi.c
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2022-07-22 05:56:30 +0800
committerGitHub <noreply@github.com>2022-07-21 17:56:30 -0400
commit5a4774cd4d90f9ea7e7f9e34b15de29463aba4c4 (patch)
tree2b1063ea2ffa7b4b13c846345256b409f7ab0276 /src/loongarch64/ffi.c
parent5264a7c5cd3460465326ebd347559828196dceb1 (diff)
downloadlibffi-5a4774cd4d90f9ea7e7f9e34b15de29463aba4c4.tar.gz
static trampoline for LoongArch (#723)
For the benefit and technical details of static trampoline, see https://github.com/libffi/libffi/pull/624. As a new architecture, let's be "safer" from the start. The change survived libffi testsuite on loongarch64-linux-gnu.
Diffstat (limited to 'src/loongarch64/ffi.c')
-rw-r--r--src/loongarch64/ffi.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/loongarch64/ffi.c b/src/loongarch64/ffi.c
index 7a28892..ed9c15f 100644
--- a/src/loongarch64/ffi.c
+++ b/src/loongarch64/ffi.c
@@ -519,8 +519,16 @@ ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
return FFI_BAD_ABI;
- /* We will call ffi_closure_inner with codeloc, not closure, but as long
- as the memory is readable it should work. */
+#if defined(FFI_EXEC_STATIC_TRAMP)
+ if (ffi_tramp_is_present(closure))
+ {
+ ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure);
+ goto out;
+ }
+#endif
+
+ /* Fill the dynamic trampoline. We will call ffi_closure_inner with codeloc,
+ not closure, but as long as the memory is readable it should work. */
tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */
tramp[1] = 0x28c0418d; /* ld.d $t1, $t0, 16 */
tramp[2] = 0x4c0001a0; /* jirl $zero, $t1, 0 */
@@ -528,11 +536,13 @@ ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
tramp[4] = fn;
tramp[5] = fn >> 32;
+ __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
+
+out:
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
- __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
return FFI_OK;
}
@@ -593,3 +603,17 @@ ffi_closure_inner (ffi_cif *cif,
marshal (&cb, cif->rtype, 0, rvalue);
}
}
+
+#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 = 16;
+ /* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and
+ 64K. */
+ *map_size = 1 << 16;
+ return &trampoline_code_table;
+}
+#endif