Fix handling of variadic calls on Darwin/AArch64

This commit is contained in:
Ole André Vadla Ravnås
2014-04-06 20:54:13 +02:00
parent dc33cb3c99
commit 419503f409
2 changed files with 41 additions and 2 deletions

View File

@@ -408,6 +408,10 @@ struct arg_state
unsigned ngrn; /* Next general-purpose register number. */ unsigned ngrn; /* Next general-purpose register number. */
unsigned nsrn; /* Next vector register number. */ unsigned nsrn; /* Next vector register number. */
size_t nsaa; /* Next stack offset. */ size_t nsaa; /* Next stack offset. */
#if defined (__APPLE__)
unsigned allocating_variadic;
#endif
}; };
/* Initialize a procedure call argument marshalling state. */ /* Initialize a procedure call argument marshalling state. */
@@ -417,6 +421,10 @@ arg_init (struct arg_state *state, size_t call_frame_size)
state->ngrn = 0; state->ngrn = 0;
state->nsrn = 0; state->nsrn = 0;
state->nsaa = 0; state->nsaa = 0;
#if defined (__APPLE__)
state->allocating_variadic = 0;
#endif
} }
/* Return the number of available consecutive core argument /* Return the number of available consecutive core argument
@@ -476,7 +484,10 @@ allocate_to_stack (struct arg_state *state, void *stack, size_t alignment,
alignment of the argument's type. */ alignment of the argument's type. */
state->nsaa = ALIGN (state->nsaa, alignment); state->nsaa = ALIGN (state->nsaa, alignment);
state->nsaa = ALIGN (state->nsaa, alignment); state->nsaa = ALIGN (state->nsaa, alignment);
#if !defined (__APPLE__) #if defined (__APPLE__)
if (state->allocating_variadic)
state->nsaa = ALIGN (state->nsaa, 8);
#else
state->nsaa = ALIGN (state->nsaa, 8); state->nsaa = ALIGN (state->nsaa, 8);
#endif #endif
@@ -725,6 +736,16 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack,
FFI_ASSERT (0); FFI_ASSERT (0);
break; break;
} }
#if defined (__APPLE__)
if (i + 1 == ecif->cif->aarch64_nfixedargs)
{
state.ngrn = N_X_ARG_REG;
state.nsrn = N_V_ARG_REG;
state.allocating_variadic = 1;
}
#endif
} }
return ecif->cif->aarch64_flags; return ecif->cif->aarch64_flags;
@@ -761,6 +782,20 @@ ffi_prep_cif_machdep (ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
#if defined (__APPLE__)
/* Perform Apple-specific cif processing for variadic calls */
ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
unsigned int nfixedargs,
unsigned int ntotalargs)
{
cif->aarch64_nfixedargs = nfixedargs;
return ffi_prep_cif_machdep(cif);
}
#endif
/* Call a function with the provided arguments and capture the return /* Call a function with the provided arguments and capture the return
value. */ value. */
void void

View File

@@ -47,8 +47,12 @@ typedef enum ffi_abi
/* ---- Internal ---- */ /* ---- Internal ---- */
#if defined (__APPLE__)
#define FFI_TARGET_SPECIFIC_VARIADIC
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags; unsigned aarch64_nfixedargs
#else
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags
#endif
#define AARCH64_FFI_WITH_V_BIT 0 #define AARCH64_FFI_WITH_V_BIT 0