diff options
author | AndreRH <andre.hentschel@ok.de> | 2020-11-10 12:27:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-10 06:27:59 -0500 |
commit | 56f7df711f70414d4f3663b34e54b122b38bab88 (patch) | |
tree | eb5e80eca84aa55a375883100f4d37a1d6244d85 /src/aarch64 | |
parent | 8111cd06921e80d5d7192ce8d1f64733072fdbcd (diff) | |
download | libffi-56f7df711f70414d4f3663b34e54b122b38bab88.tar.gz |
aarch64: Allow FFI_WIN64 for winelib (#593)
Diffstat (limited to 'src/aarch64')
-rw-r--r-- | src/aarch64/ffi.c | 70 | ||||
-rw-r--r-- | src/aarch64/ffitarget.h | 7 | ||||
-rw-r--r-- | src/aarch64/internal.h | 1 |
3 files changed, 47 insertions, 31 deletions
diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c index 508a624..ef09f4d 100644 --- a/src/aarch64/ffi.c +++ b/src/aarch64/ffi.c @@ -564,6 +564,14 @@ ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, cif->aarch64_nfixedargs = nfixedargs; return status; } +#else +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs) +{ + ffi_status status = ffi_prep_cif_machdep (cif); + cif->flags |= AARCH64_FLAG_VARARG; + return status; +} #endif /* __APPLE__ */ extern void ffi_call_SYSV (struct call_context *context, void *frame, @@ -580,7 +588,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, void *stack, *frame, *rvalue; struct arg_state state; size_t stack_bytes, rtype_size, rsize; - int i, nargs, flags; + int i, nargs, flags, isvariadic = 0; ffi_type *rtype; flags = cif->flags; @@ -588,6 +596,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, rtype_size = rtype->size; stack_bytes = cif->bytes; + if (flags & AARCH64_FLAG_VARARG) + { + isvariadic = 1; + flags &= ~AARCH64_FLAG_VARARG; + } + /* If the target function returns a structure via hidden pointer, then we cannot allow a null rvalue. Otherwise, mash a null rvalue to void return type. */ @@ -667,35 +681,31 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, h = is_vfp_type (ty); if (h) { - int elems = 4 - (h & 3); -#ifdef _WIN32 /* for handling armasm calling convention */ - if (cif->is_variadic) - { - if (state.ngrn + elems <= N_X_ARG_REG) - { - dest = &context->x[state.ngrn]; - state.ngrn += elems; - extend_hfa_type(dest, a, h); - break; - } - state.nsrn = N_X_ARG_REG; - dest = allocate_to_stack(&state, stack, ty->alignment, s); - } - else - { -#endif /* for handling armasm calling convention */ - if (state.nsrn + elems <= N_V_ARG_REG) - { - dest = &context->v[state.nsrn]; - state.nsrn += elems; - extend_hfa_type (dest, a, h); - break; - } - state.nsrn = N_V_ARG_REG; - dest = allocate_to_stack (&state, stack, ty->alignment, s); -#ifdef _WIN32 /* for handling armasm calling convention */ - } -#endif /* for handling armasm calling convention */ + int elems = 4 - (h & 3); + if (cif->abi == FFI_WIN64 && isvariadic) + { + if (state.ngrn + elems <= N_X_ARG_REG) + { + dest = &context->x[state.ngrn]; + state.ngrn += elems; + extend_hfa_type(dest, a, h); + break; + } + state.nsrn = N_X_ARG_REG; + dest = allocate_to_stack(&state, stack, ty->alignment, s); + } + else + { + if (state.nsrn + elems <= N_V_ARG_REG) + { + dest = &context->v[state.nsrn]; + state.nsrn += elems; + extend_hfa_type (dest, a, h); + break; + } + state.nsrn = N_V_ARG_REG; + dest = allocate_to_stack (&state, stack, ty->alignment, s); + } } else if (s > 16) { diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h index 7a8cabe..d5622e1 100644 --- a/src/aarch64/ffitarget.h +++ b/src/aarch64/ffitarget.h @@ -45,8 +45,13 @@ typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_SYSV, + FFI_WIN64, FFI_LAST_ABI, +#if defined(_WIN32) + FFI_DEFAULT_ABI = FFI_WIN64 +#else FFI_DEFAULT_ABI = FFI_SYSV +#endif } ffi_abi; #endif @@ -72,11 +77,11 @@ typedef enum ffi_abi #ifdef _WIN32 #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic #endif +#define FFI_TARGET_SPECIFIC_VARIADIC /* ---- Internal ---- */ #if defined (__APPLE__) -#define FFI_TARGET_SPECIFIC_VARIADIC #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs #elif !defined(_WIN32) /* iOS and Windows reserve x18 for the system. Disable Go closures until diff --git a/src/aarch64/internal.h b/src/aarch64/internal.h index 9c3e077..3d4d035 100644 --- a/src/aarch64/internal.h +++ b/src/aarch64/internal.h @@ -61,6 +61,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define AARCH64_FLAG_ARG_V_BIT 7 #define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT) +#define AARCH64_FLAG_VARARG (1 << 8) #define N_X_ARG_REG 8 #define N_V_ARG_REG 8 |