summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnthony Green <green@moxielogic.com>2022-05-29 10:28:10 -0400
committerAnthony Green <green@moxielogic.com>2022-05-29 10:28:10 -0400
commitaa2c4141722ec8b8b014b97e049ffa2d140d0c0d (patch)
tree1a73bf1d5d4cdd41cb589524fe241f9a64efe075 /src
parent36b265ae438a364722c98136ba79cb450a48fca3 (diff)
downloadlibffi-aa2c4141722ec8b8b014b97e049ffa2d140d0c0d.tar.gz
64-bit cygwin: fix struct args. Document change.
Diffstat (limited to 'src')
-rw-r--r--src/x86/ffiw64.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/x86/ffiw64.c b/src/x86/ffiw64.c
index 6870d07..81d41bf 100644
--- a/src/x86/ffiw64.c
+++ b/src/x86/ffiw64.c
@@ -123,9 +123,26 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
UINT64 *stack;
size_t rsize;
struct win64_call_frame *frame;
+ ffi_type **arg_types = cif->arg_types;
+ int nargs = cif->nargs;
+ const int max_reg_struct_size = cif->abi == FFI_GNUW64 ? 8 : 16;
FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);
+ /* If we have any large structure arguments, make a copy so we are passing
+ by value. */
+ for (i = 0; i < nargs; i++)
+ {
+ ffi_type *at = arg_types[i];
+ int size = at->size;
+ if (at->type == FFI_TYPE_STRUCT && size > max_reg_struct_size)
+ {
+ char *argcopy = alloca (size);
+ memcpy (argcopy, avalue[i], size);
+ avalue[i] = argcopy;
+ }
+ }
+
flags = cif->flags;
rsize = 0;