1a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ----------------------------------------------------------------------- 2a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi.c 3a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 4a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project m68k Foreign Function Interface 5a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ----------------------------------------------------------------------- */ 6a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 7a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi.h> 8a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi_common.h> 9a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 10a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <stdlib.h> 11a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <unistd.h> 12a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <sys/syscall.h> 13a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <asm/cachectl.h> 14a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 15a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_call_SYSV (extended_cif *, 16a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned, 17a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *, void (*fn) ()); 18a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid *ffi_prep_args (void *stack, extended_cif *ecif); 19a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_closure_SYSV (ffi_closure *); 20a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_closure_struct_SYSV (ffi_closure *); 21a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectunsigned int ffi_closure_SYSV_inner (ffi_closure *closure, 22a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *resp, void *args); 23a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 24a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ffi_prep_args is called by the assembly routine once stack space has 25a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project been allocated for the function's arguments. */ 26a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 27a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid * 28a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_args (void *stack, extended_cif *ecif) 29a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 30a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int i; 31a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **p_argv; 32a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project char *argp; 33a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_type **p_arg; 34a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *struct_value_ptr; 35a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 36a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 37a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 38a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (ecif->cif->rtype->type == FFI_TYPE_STRUCT 39a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && !ecif->cif->flags) 40a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project struct_value_ptr = ecif->rvalue; 41a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 42a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project struct_value_ptr = NULL; 43a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 44a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = ecif->avalue; 45a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 46a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; 47a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project i != 0; 48a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project i--, p_arg++) 49a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 50a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 51a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 52a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 53a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof (int)) 54a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 55a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 56a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 57a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 58a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; 59a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 60a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 61a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 62a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; 63a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 64a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 65a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 66a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; 67a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 68a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 69a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 70a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; 71a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 72a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 73a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 74a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp + sizeof (int) - z, *p_argv, z); 75a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 76a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 77a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 78a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (0); 79a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 80a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof (int); 81a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 82a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 83a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 84a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (argp, *p_argv, z); 85a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 86a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Align if necessary. */ 87a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((sizeof(int) - 1) & z) 88a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = ALIGN(z, sizeof(int)); 89a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 90a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 91a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv++; 92a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 93a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 94a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 95a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return struct_value_ptr; 96a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 97a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 98a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_INT 1 99a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_DINT 2 100a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_FLOAT 4 101a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_DOUBLE 8 102a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_LDOUBLE 16 103a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_POINTER 32 104a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_STRUCT1 64 105a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define CIF_FLAGS_STRUCT2 128 106a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 107a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Perform machine dependent cif processing */ 108a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 109a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_cif_machdep (ffi_cif *cif) 110a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 111a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set the return type flag */ 112a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->rtype->type) 113a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 114a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_VOID: 115a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = 0; 116a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 117a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 118a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 119a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->rtype->size) 120a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 121a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case 1: 122a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_STRUCT1; 123a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 124a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case 2: 125a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_STRUCT2; 126a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 127a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case 4: 128a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_INT; 129a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 130a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case 8: 131a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_DINT; 132a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 133a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 134a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = 0; 135a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 136a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 137a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 138a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 139a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 140a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_FLOAT; 141a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 142a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 143a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 144a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_DOUBLE; 145a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 146a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 147a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_LONGDOUBLE: 148a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_LDOUBLE; 149a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 150a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 151a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_POINTER: 152a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_POINTER; 153a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 154a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 155a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT64: 156a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT64: 157a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_DINT; 158a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 159a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 160a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 161a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = CIF_FLAGS_INT; 162a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 163a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 164a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 165a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 166a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 167a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 168a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid 169a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) 170a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 171a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project extended_cif ecif; 172a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 173a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.cif = cif; 174a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.avalue = avalue; 175a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 176a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* If the return value is a struct and we don't have a return value 177a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project address then we need to make one. */ 178a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 179a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (rvalue == NULL 180a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && cif->rtype->type == FFI_TYPE_STRUCT 181a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && cif->rtype->size > 8) 182a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = alloca (cif->rtype->size); 183a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 184a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = rvalue; 185a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 186a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->abi) 187a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 188a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_SYSV: 189a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_SYSV (&ecif, cif->bytes, cif->flags, 190a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue, fn); 191a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 192a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 193a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 194a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (0); 195a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 196a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 197a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 198a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 199a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic void 200a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) 201a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 202a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int i; 203a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **p_argv; 204a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project char *argp; 205a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_type **p_arg; 206a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 207a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 208a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = avalue; 209a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 210a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) 211a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 212a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 213a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 214a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 215a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z <= 4) 216a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 217a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *p_argv = (void *) (argp + 4 - z); 218a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 219a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = 4; 220a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 221a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 222a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 223a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *p_argv = (void *) argp; 224a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 225a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Align if necessary */ 226a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((sizeof(int) - 1) & z) 227a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = ALIGN(z, sizeof(int)); 228a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 229a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 230a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv++; 231a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 232a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 233a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 234a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 235a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectunsigned int 236a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args) 237a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 238a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif; 239a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **arg_area; 240a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 241a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 242a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project arg_area = (void**) alloca (cif->nargs * sizeof (void *)); 243a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 244a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_prep_incoming_args_SYSV(args, arg_area, cif); 245a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 246a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (closure->fun) (cif, resp, arg_area, closure->user_data); 247a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 248a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return cif->flags; 249a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 250a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 251a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 252a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_closure_loc (ffi_closure* closure, 253a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif* cif, 254a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fun)(ffi_cif*,void*,void**,void*), 255a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *user_data, 256a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *codeloc) 257a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 258a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (cif->abi == FFI_SYSV); 259a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 260a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned short *)closure->tramp = 0x207c; 261a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **)(closure->tramp + 2) = codeloc; 262a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned short *)(closure->tramp + 6) = 0x4ef9; 263a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->rtype->type == FFI_TYPE_STRUCT 264a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project && !cif->flags) 265a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV; 266a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 267a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **)(closure->tramp + 8) = ffi_closure_SYSV; 268a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 269a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, 270a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); 271a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 272a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->cif = cif; 273a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->user_data = user_data; 274a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->fun = fun; 275a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 276a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 277a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 278a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 279