diff options
author | Anthony Green <green@moxielogic.com> | 2022-05-28 19:59:35 -0400 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2022-05-28 19:59:35 -0400 |
commit | 769b7366d2312c7efdfa605cf1fc1156b94ba2e0 (patch) | |
tree | 03e9f5dc0cc977ae29c487bb1e1431efdc3d75c2 /src | |
parent | faafcb9df9aebdde1415a73d17fe9e943d97d455 (diff) | |
download | libffi-769b7366d2312c7efdfa605cf1fc1156b94ba2e0.tar.gz |
Fix for MS x64 ABI
Diffstat (limited to 'src')
-rw-r--r-- | src/x86/ffi64.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c index 74a3003..22d43f5 100644 --- a/src/x86/ffi64.c +++ b/src/x86/ffi64.c @@ -581,6 +581,9 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, flags = UNIX64_RET_VOID; } + arg_types = cif->arg_types; + avn = cif->nargs; + /* Allocate the space for the arguments, plus 4 words of temp space. */ stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8); reg_args = (struct register_args *) stack; @@ -595,9 +598,6 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, if (flags & UNIX64_FLAG_RET_IN_MEM) reg_args->gpr[gprcount++] = (unsigned long) rvalue; - avn = cif->nargs; - arg_types = cif->arg_types; - for (i = 0; i < avn; ++i) { size_t n, size = arg_types[i]->size; @@ -613,11 +613,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, if (align < 8) align = 8; - /* Pass this argument in memory. */ - argp = (void *) FFI_ALIGN (argp, align); - memcpy (argp, avalue[i], size); - argp += size; - } + /* Pass this argument in memory. */ + argp = (void *) FFI_ALIGN (argp, align); + memcpy (argp, avalue[i], size); + + argp += size; + } else { /* The argument is passed entirely in registers. */ @@ -683,6 +684,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { ffi_type **arg_types = cif->arg_types; int i, nargs = cif->nargs; + const int max_reg_struct_size = cif->abi == FFI_GNUW64 ? 8 : 16; /* If we have any large structure arguments, make a copy so we are passing by value. */ @@ -690,7 +692,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { ffi_type *at = arg_types[i]; int size = at->size; - if (at->type == FFI_TYPE_STRUCT && size > 16) + if (at->type == FFI_TYPE_STRUCT && size > max_reg_struct_size) { char *argcopy = alloca (size); memcpy (argcopy, avalue[i], size); |