public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: madvenka@linux.microsoft.com
To: libffi-discuss@sourceware.org
Cc: green@moxielogic.com, fweimer@redhat.com, dj@redhat.com,
	madvenka@linux.microsoft.com
Subject: [RFC PATCH v3 5/5] arm: Support for Static Trampolines
Date: Fri, 15 Jan 2021 12:46:53 -0600	[thread overview]
Message-ID: <20210115184653.124913-6-madvenka@linux.microsoft.com> (raw)
In-Reply-To: <20210115184653.124913-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>

	- Define the arch-specific initialization function ffi_tramp_arch ()
	  that returns trampoline size information to common code.

	- Define the trampoline code mapping and data mapping sizes.

	- Define the trampoline code table statically.

	- Introduce a tiny prolog for each ABI handling function. The ABI
	  handlers addressed are:

	  	- ffi_closure_SYSV
		- ffi_closure_VFP

	  The prolog functions are called:

	  	- ffi_closure_SYSV_alt
		- ffi_closure_VFP_alt

	  The legacy trampoline jumps to the ABI handler. The static
	  trampoline jumps to the prolog function. The prolog function uses
	  the information provided by the static trampoline, sets things up
	  for the ABI handler and then jumps to the ABI handler.

	- Call ffi_closure_tramp_init () in ffi_prep_closure_loc () to
	  initialize static trampoline parameters.

Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
---
 src/arm/ffi.c      | 29 ++++++++++++++++++++++++++++-
 src/arm/internal.h | 10 ++++++++++
 src/arm/sysv.S     | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/src/arm/ffi.c b/src/arm/ffi.c
index 0058390..7e3cf1a 100644
--- a/src/arm/ffi.c
+++ b/src/arm/ffi.c
@@ -570,7 +570,9 @@ ffi_closure_inner_VFP (ffi_cif *cif,
 }
 
 void ffi_closure_SYSV (void) FFI_HIDDEN;
+void ffi_closure_SYSV_alt (void) FFI_HIDDEN;
 void ffi_closure_VFP (void) FFI_HIDDEN;
+void ffi_closure_VFP_alt (void) FFI_HIDDEN;
 
 #ifdef FFI_GO_CLOSURES
 void ffi_go_closure_SYSV (void) FFI_HIDDEN;
@@ -596,12 +598,16 @@ ffi_prep_closure_loc (ffi_closure * closure,
 		      void *user_data, void *codeloc)
 {
   void (*closure_func) (void) = ffi_closure_SYSV;
+  void (*closure_func_alt) (void) = ffi_closure_SYSV_alt;
 
   if (cif->abi == FFI_VFP)
     {
       /* We only need take the vfp path if there are vfp arguments.  */
       if (cif->vfp_used)
-	closure_func = ffi_closure_VFP;
+	{
+	  closure_func = ffi_closure_VFP;
+	  closure_func_alt = ffi_closure_VFP_alt;
+	}
     }
   else if (cif->abi != FFI_SYSV)
     return FFI_BAD_ABI;
@@ -612,6 +618,14 @@ ffi_prep_closure_loc (ffi_closure * closure,
   config[1] = closure_func;
 #else
 
+  if (ffi_tramp_is_present(closure))
+    {
+      /* Initialize the static trampoline's parameters. */
+      ffi_tramp_set_parms (closure->ftramp, closure_func_alt, closure);
+      goto out;
+    }
+
+  /* Initialize the dynamic trampoline. */
 #ifndef _M_ARM
   memcpy(closure->tramp, ffi_arm_trampoline, 8);
 #else
@@ -633,6 +647,7 @@ ffi_prep_closure_loc (ffi_closure * closure,
 #else
   *(void (**)(void))(closure->tramp + 8) = closure_func;
 #endif
+out:
 #endif
 
   closure->cif = cif;
@@ -873,4 +888,16 @@ layout_vfp_args (ffi_cif * cif)
     }
 }
 
+#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 = ARM_TRAMP_SIZE;
+  *map_size = ARM_TRAMP_MAP_SIZE;
+  return &trampoline_code_table;
+}
+#endif
+
 #endif /* __arm__ or _M_ARM */
diff --git a/src/arm/internal.h b/src/arm/internal.h
index 6cf0b2a..fa8ab0b 100644
--- a/src/arm/internal.h
+++ b/src/arm/internal.h
@@ -5,3 +5,13 @@
 #define ARM_TYPE_INT	4
 #define ARM_TYPE_VOID	5
 #define ARM_TYPE_STRUCT	6
+
+#if defined(FFI_EXEC_STATIC_TRAMP)
+/*
+ * For the trampoline table mapping, a mapping size of 4K (base page size)
+ * is chosen.
+ */
+#define ARM_TRAMP_MAP_SHIFT	12
+#define ARM_TRAMP_MAP_SIZE	(1 << ARM_TRAMP_MAP_SHIFT)
+#define ARM_TRAMP_SIZE		20
+#endif
diff --git a/src/arm/sysv.S b/src/arm/sysv.S
index 74bc53f..ea39465 100644
--- a/src/arm/sysv.S
+++ b/src/arm/sysv.S
@@ -260,6 +260,12 @@ ARM_FUNC_START(ffi_closure_SYSV)
 	UNWIND(.fnend)
 ARM_FUNC_END(ffi_closure_SYSV)
 
+ARM_FUNC_START(ffi_closure_SYSV_alt)
+	ldr	ip, [sp, #4]
+	add	sp, sp, 8
+	b	CNAME(ffi_closure_SYSV)
+ARM_FUNC_END(ffi_closure_SYSV_alt)
+
 ARM_FUNC_START(ffi_go_closure_VFP)
 	cfi_startproc
 	stmdb	sp!, {r0-r3}			@ save argument regs
@@ -310,6 +316,12 @@ ARM_FUNC_START(ffi_closure_VFP)
 	UNWIND(.fnend)
 ARM_FUNC_END(ffi_closure_VFP)
 
+ARM_FUNC_START(ffi_closure_VFP_alt)
+	ldr	ip, [sp, #4]
+	add	sp, sp, 8
+	b	CNAME(ffi_closure_VFP)
+ARM_FUNC_END(ffi_closure_VFP_alt)
+
 /* Load values returned in registers for both closure entry points.
    Note that we use LDM with SP in the register set.  This is deprecated
    by ARM, but not yet unpredictable.  */
@@ -354,6 +366,39 @@ E(ARM_TYPE_STRUCT)
 	cfi_endproc
 ARM_FUNC_END(ffi_closure_ret)
 
+#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 register ip (r12). It saves the original value of ip
+ * 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 ip
+ * - load the data address in a register
+ * - restore the stack pointer to what it was when the trampoline was invoked.
+ */
+	.align	ARM_TRAMP_MAP_SHIFT
+ARM_FUNC_START(trampoline_code_table)
+	.rept	ARM_TRAMP_MAP_SIZE / ARM_TRAMP_SIZE
+	sub	sp, sp, #8		/* Make space on the stack */
+	str	ip, [sp]		/* Save ip on stack */
+	ldr	ip, [pc, #4080]		/* Copy data into ip */
+	str	ip, [sp, #4]		/* Save data on stack */
+	ldr	pc, [pc, #4076]		/* Copy code into PC */
+	.endr
+ARM_FUNC_END(trampoline_code_table)
+	.align	ARM_TRAMP_MAP_SHIFT
+#endif /* FFI_EXEC_STATIC_TRAMP */
+
 #if FFI_EXEC_TRAMPOLINE_TABLE
 
 #ifdef __MACH__
-- 
2.25.1


  parent reply	other threads:[~2021-01-15 18:47 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1ef5c7e1c9a6ebb140a476ba555ec955681f4fba>
2021-01-15 18:46 ` [RFC PATCH v3 0/5] Libffi " madvenka
2021-01-15 18:46   ` [RFC PATCH v3 1/5] " madvenka
2021-01-27  3:31     ` DJ Delorie
2021-01-27 21:51       ` Madhavan T. Venkataraman
2021-01-27 22:15         ` DJ Delorie
2021-01-27 22:43           ` Madhavan T. Venkataraman
2021-01-15 18:46   ` [RFC PATCH v3 2/5] x86: Support for " madvenka
2021-01-27  3:31     ` DJ Delorie
2021-01-28 21:59       ` Madhavan T. Venkataraman
2021-01-28 22:17         ` DJ Delorie
2021-01-28 23:25           ` Madhavan T. Venkataraman
2021-01-29  2:09             ` DJ Delorie
2021-01-29  2:38               ` Madhavan T. Venkataraman
2021-01-29  2:48                 ` DJ Delorie
2021-01-29  3:24                   ` Madhavan T. Venkataraman
2021-01-29  6:07                     ` DJ Delorie
2021-02-01 19:46                 ` DJ Delorie
2021-01-15 18:46   ` [RFC PATCH v3 3/5] i386: " madvenka
2021-01-15 18:46   ` [RFC PATCH v3 4/5] arm64: " madvenka
2021-01-15 18:46   ` madvenka [this message]
2021-01-26 23:41   ` [RFC PATCH v3 0/5] Libffi " Anthony Green
2021-01-27 17:20     ` Madhavan T. Venkataraman
2021-01-27 18:00       ` Anthony Green
2021-01-27 19:45         ` Madhavan T. Venkataraman
2021-01-28 14:21           ` Anthony Green
2021-01-28 17:01             ` Madhavan T. Venkataraman
2021-02-05 18:20               ` Madhavan T. Venkataraman
2021-02-05 18:46                 ` Anthony Green
2021-02-05 19:38                   ` Madhavan T. Venkataraman
2021-02-07 16:09                     ` Madhavan T. Venkataraman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210115184653.124913-6-madvenka@linux.microsoft.com \
    --to=madvenka@linux.microsoft.com \
    --cc=dj@redhat.com \
    --cc=fweimer@redhat.com \
    --cc=green@moxielogic.com \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).