From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13172 invoked by alias); 20 Sep 2017 08:51:17 -0000 Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org Received: (qmail 13160 invoked by uid 89); 20 Sep 2017 08:51:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=HTo:U*libffi-discuss, H*Ad:U*libffi-discuss, H*r:sk:libffi-, 2866 X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 20 Sep 2017 08:51:15 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 528455CB22 for ; Wed, 20 Sep 2017 08:51:13 +0000 (UTC) From: Andreas Schwab To: libffi-discuss@sourceware.org Subject: [PATCH] Fix passing struct by value on aarch64 X-Yow: Either CONFESS now or we go to ``PEOPLE'S COURT''!! Date: Wed, 20 Sep 2017 08:51:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2017/txt/msg00019.txt.bz2 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."