public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Andreas Schwab <schwab@suse.de>
To: libffi-discuss@sourceware.org
Subject: [PATCH] Fix passing struct by value on aarch64
Date: Wed, 20 Sep 2017 08:51:00 -0000	[thread overview]
Message-ID: <mvmy3p93g90.fsf@suse.de> (raw)

This fixes the Python ctype tests.

---
 src/aarch64/ffi.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c
index c4a6151d37..05a1b8a9a2 100644
--- a/src/aarch64/ffi.c
+++ b/src/aarch64/ffi.c
@@ -238,13 +238,18 @@ is_vfp_type (const ffi_type *ty)
    state.
 
    The terse state variable names match the names used in the AARCH64
-   PCS. */
+   PCS.
+
+   The struct area is allocated downwards from the top of the argument
+   area.  It is used to hold copies of structures passed by value that are
+   bigger than 16 bytes.  */
 
 struct arg_state
 {
   unsigned ngrn;                /* Next general-purpose register number. */
   unsigned nsrn;                /* Next vector register number. */
   size_t nsaa;                  /* Next stack offset. */
+  size_t next_struct_area;	/* Place to allocate big structs. */
 
 #if defined (__APPLE__)
   unsigned allocating_variadic;
@@ -253,11 +258,12 @@ struct arg_state
 
 /* Initialize a procedure call argument marshalling state.  */
 static void
-arg_init (struct arg_state *state)
+arg_init (struct arg_state *state, size_t size)
 {
   state->ngrn = 0;
   state->nsrn = 0;
   state->nsaa = 0;
+  state->next_struct_area = size;
 #if defined (__APPLE__)
   state->allocating_variadic = 0;
 #endif
@@ -286,6 +292,21 @@ allocate_to_stack (struct arg_state *state, void *stack,
   return (char *)stack + nsaa;
 }
 
+/* Allocate and copy a structure that is passed by value on the stack and
+   return a pointer to it.  */
+static void *
+allocate_and_copy_struct_to_stack (struct arg_state *state, void *stack,
+				   size_t alignment, size_t size, void *value)
+{
+  size_t dest = state->next_struct_area - size;
+
+  /* Round down to the natural alignment of the value.  */
+  dest = ALIGN_DOWN (dest, alignment);
+  state->next_struct_area = dest;
+
+  return memcpy ((char *) stack + dest, value, size);
+}
+
 static ffi_arg
 extend_integer_type (void *source, int type)
 {
@@ -591,13 +612,14 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
   frame = stack + stack_bytes;
   rvalue = (rsize ? frame + 32 : orig_rvalue);
 
-  arg_init (&state);
+  arg_init (&state, stack_bytes);
   for (i = 0, nargs = cif->nargs; i < nargs; i++)
     {
       ffi_type *ty = cif->arg_types[i];
       size_t s = ty->size;
       void *a = avalue[i];
       int h, t;
+      void *dest;
 
       t = ty->type;
       switch (t)
@@ -645,8 +667,6 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
 	case FFI_TYPE_STRUCT:
 	case FFI_TYPE_COMPLEX:
 	  {
-	    void *dest;
-
 	    h = is_vfp_type (ty);
 	    if (h)
 	      {
@@ -664,9 +684,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
 	    else if (s > 16)
 	      {
 		/* If the argument is a composite type that is larger than 16
-		   bytes, then the argument has been copied to memory, and
+		   bytes, then the argument is copied to memory, and
 		   the argument is replaced by a pointer to the copy.  */
-		a = &avalue[i];
+		dest = allocate_and_copy_struct_to_stack (&state, stack,
+							  ty->alignment, s,
+							  avalue[i]);
+		a = &dest;
 		t = FFI_TYPE_POINTER;
 		s = sizeof (void *);
 		goto do_pointer;
@@ -835,7 +858,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
   int i, h, nargs, flags;
   struct arg_state state;
 
-  arg_init (&state);
+  arg_init (&state, cif->bytes);
 
   for (i = 0, nargs = cif->nargs; i < nargs; i++)
     {
-- 
2.14.1


-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

                 reply	other threads:[~2017-09-20  8:51 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=mvmy3p93g90.fsf@suse.de \
    --to=schwab@suse.de \
    --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).