1a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ----------------------------------------------------------------------- 2a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc. 3a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (c) 2002 Ranjit Mathew 4a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (c) 2002 Bo Thorsen 5a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (c) 2002 Roger Sayle 6a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Copyright (C) 2008 Free Software Foundation, Inc. 7a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 8a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project x86 Foreign Function Interface 9a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 10a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project Permission is hereby granted, free of charge, to any person obtaining 11a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project a copy of this software and associated documentation files (the 12a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ``Software''), to deal in the Software without restriction, including 13a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project without limitation the rights to use, copy, modify, merge, publish, 14a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project distribute, sublicense, and/or sell copies of the Software, and to 15a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project permit persons to whom the Software is furnished to do so, subject to 16a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project the following conditions: 17a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 18a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project The above copyright notice and this permission notice shall be included 19a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project in all copies or substantial portions of the Software. 20a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 21a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 22a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project DEALINGS IN THE SOFTWARE. 29a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ----------------------------------------------------------------------- */ 30a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 31a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifndef __x86_64__ 32a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 33a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi.h> 34a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <ffi_common.h> 35a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 36a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include <stdlib.h> 37a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 38a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ffi_prep_args is called by the assembly routine once stack space 39a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project has been allocated for the function's arguments */ 40a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 41a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_prep_args(char *stack, extended_cif *ecif) 42a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 43a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int i; 44a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register void **p_argv; 45a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register char *argp; 46a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register ffi_type **p_arg; 47a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 48a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 49a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 50a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (ecif->cif->flags == FFI_TYPE_STRUCT) 51a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 52a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(void **) argp = ecif->rvalue; 53a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += 4; 54a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 55a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 56a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = ecif->avalue; 57a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 58a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; 59a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project i != 0; 60a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project i--, p_arg++) 61a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 62a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 63a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 64a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Align if necessary */ 65a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((sizeof(int) - 1) & (unsigned) argp) 66a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = (char *) ALIGN(argp, sizeof(int)); 67a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 68a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 69a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (z < sizeof(int)) 70a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 71a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = sizeof(int); 72a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch ((*p_arg)->type) 73a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 74a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 75a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); 76a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 77a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 78a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 79a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); 80a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 81a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 82a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 83a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); 84a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 85a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 86a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 87a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); 88a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 89a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 90a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT32: 91a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); 92a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 93a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 94a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT32: 95a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 96a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 97a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 98a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 99a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); 100a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 101a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 102a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 103a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 104a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 105a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 106a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 107a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 108a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy(argp, *p_argv, z); 109a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 110a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv++; 111a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 112a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 113a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 114a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return; 115a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 116a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 117a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Perform machine dependent cif processing */ 118a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status ffi_prep_cif_machdep(ffi_cif *cif) 119a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 120a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Set the return type flag */ 121a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->rtype->type) 122a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 123a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_VOID: 124a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86 125a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 126a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 127a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if defined(X86) || defined(X86_DARWIN) 128a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT8: 129a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT16: 130a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT8: 131a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT16: 132a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 133a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 134a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_SINT64: 135a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_FLOAT: 136a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_DOUBLE: 137a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_LONGDOUBLE: 138a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = (unsigned) cif->rtype->type; 139a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 140a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 141a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_UINT64: 142a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_SINT64; 143a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 144a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 145a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifndef X86 146a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_TYPE_STRUCT: 147a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->rtype->size == 1) 148a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 149a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ 150a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 151a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (cif->rtype->size == 2) 152a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 153a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */ 154a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 155a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (cif->rtype->size == 4) 156a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 157a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_INT; /* same as int type */ 158a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 159a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (cif->rtype->size == 8) 160a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 161a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ 162a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 163a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 164a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 165a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_STRUCT; 166a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 167a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 168a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 169a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 170a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 171a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->flags = FFI_TYPE_INT; 172a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 173a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 174a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 175a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_DARWIN 176a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif->bytes = (cif->bytes + 15) & ~0xF; 177a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 178a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 179a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 180a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 181a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 182a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, 183a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned, unsigned *, void (*fn)(void)); 184a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 185a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 186a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, 187a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned, unsigned *, void (*fn)(void)); 188a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 189a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif /* X86_WIN32 */ 190a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 191a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 192a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 193a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project extended_cif ecif; 194a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 195a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.cif = cif; 196a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.avalue = avalue; 197a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 198a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* If the return value is a struct and we don't have a return */ 199a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* value address then we need to make one */ 200a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 201a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((rvalue == NULL) && 202a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (cif->flags == FFI_TYPE_STRUCT)) 203a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 204a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = alloca(cif->rtype->size); 205a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 206a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 207a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = rvalue; 208a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 209a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 210a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->abi) 211a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 212a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_SYSV: 213a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, 214a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project fn); 215a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 216a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 217a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_STDCALL: 218a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, 219a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue, fn); 220a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 221a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif /* X86_WIN32 */ 222a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 223a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 224a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 225a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 226a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 227a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 228a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 229a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/** private members **/ 230a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 231a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic void ffi_prep_incoming_args_SYSV (char *stack, void **ret, 232a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void** args, ffi_cif* cif); 233a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) 234a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project __attribute__ ((regparm(1))); 235a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectunsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) 236a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project __attribute__ ((regparm(1))); 237a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) 238a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project __attribute__ ((regparm(1))); 239a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 240a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) 241a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project __attribute__ ((regparm(1))); 242a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 243a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 244a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* This function is jumped to by the trampoline */ 245a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 246a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectunsigned int FFI_HIDDEN 247a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_closure_SYSV_inner (closure, respp, args) 248a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_closure *closure; 249a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **respp; 250a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *args; 251a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 252a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* our various things... */ 253a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif; 254a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **arg_area; 255a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 256a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project cif = closure->cif; 257a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project arg_area = (void**) alloca (cif->nargs * sizeof (void*)); 258a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 259a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* this call will initialize ARG_AREA, such that each 260a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * element in that array points to the corresponding 261a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * value on the stack; and if the function returns 262a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * a structure, it will re-set RESP to point to the 263a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * structure return address. */ 264a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 265a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); 266a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 267a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (closure->fun) (cif, *respp, arg_area, closure->user_data); 268a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 269a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return cif->flags; 270a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 271a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 272a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic void 273a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, 274a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif *cif) 275a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 276a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register unsigned int i; 277a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register void **p_argv; 278a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register char *argp; 279a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project register ffi_type **p_arg; 280a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 281a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = stack; 282a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 283a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ( cif->flags == FFI_TYPE_STRUCT ) { 284a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *rvalue = *(void **) argp; 285a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += 4; 286a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 287a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 288a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv = avalue; 289a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 290a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) 291a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 292a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project size_t z; 293a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 294a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* Align if necessary */ 295a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((sizeof(int) - 1) & (unsigned) argp) { 296a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp = (char *) ALIGN(argp, sizeof(int)); 297a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 298a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 299a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project z = (*p_arg)->size; 300a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 301a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* because we're little endian, this is what it turns into. */ 302a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 303a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *p_argv = (void*) argp; 304a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 305a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project p_argv++; 306a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project argp += z; 307a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 308a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 309a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return; 310a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 311a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 312a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ 313a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 314a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ 315a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ 316a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __fun = (unsigned int)(FUN); \ 317a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __ctx = (unsigned int)(CTX); \ 318a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __dis = __fun - (__ctx + 10); \ 319a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned char*) &__tramp[0] = 0xb8; \ 320a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ 321a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned char *) &__tramp[5] = 0xe9; \ 322a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ 323a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project }) 324a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 325a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ 326a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ 327a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __fun = (unsigned int)(FUN); \ 328a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __ctx = (unsigned int)(CTX); \ 329a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned int __dis = __fun - (__ctx + 10); \ 330a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned short __size = (unsigned short)(SIZE); \ 331a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned char*) &__tramp[0] = 0xb8; \ 332a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ 333a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned char *) &__tramp[5] = 0xe8; \ 334a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ 335a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned char *) &__tramp[10] = 0xc2; \ 336a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ 337a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project }) 338a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 339a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* the cif must already be prep'ed */ 340a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 341a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 342a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_closure_loc (ffi_closure* closure, 343a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif* cif, 344a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fun)(ffi_cif*,void*,void**,void*), 345a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *user_data, 346a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *codeloc) 347a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 348a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->abi == FFI_SYSV) 349a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 350a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_INIT_TRAMPOLINE (&closure->tramp[0], 351a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project &ffi_closure_SYSV, 352a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (void*)codeloc); 353a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 354a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 355a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else if (cif->abi == FFI_STDCALL) 356a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 357a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], 358a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project &ffi_closure_STDCALL, 359a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (void*)codeloc, cif->bytes); 360a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 361a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 362a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 363a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 364a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_BAD_ABI; 365a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 366a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 367a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->cif = cif; 368a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->user_data = user_data; 369a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->fun = fun; 370a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 371a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 372a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 373a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 374a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* ------- Native raw API support -------------------------------- */ 375a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 376a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#if !FFI_NO_RAW_API 377a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 378a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_status 379a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_raw_closure_loc (ffi_raw_closure* closure, 380a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_cif* cif, 381a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 382a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *user_data, 383a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void *codeloc) 384a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 385a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project int i; 386a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 387a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if (cif->abi != FFI_SYSV) { 388a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_BAD_ABI; 389a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 390a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 391a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project // we currently don't support certain kinds of arguments for raw 392a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project // closures. This should be implemented by a separate assembly language 393a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project // routine, since it would require argument processing, something we 394a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project // don't do now for performance. 395a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 396a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project for (i = cif->nargs-1; i >= 0; i--) 397a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 398a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); 399a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); 400a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 401a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 402a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 403a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, 404a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project codeloc); 405a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 406a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->cif = cif; 407a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->user_data = user_data; 408a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project closure->fun = fun; 409a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 410a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project return FFI_OK; 411a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 412a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 413a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic void 414a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_prep_args_raw(char *stack, extended_cif *ecif) 415a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 416a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project memcpy (stack, ecif->avalue, ecif->cif->bytes); 417a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 418a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 419a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* we borrow this routine from libffi (it must be changed, though, to 420a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * actually call the function passed in the first argument. as of 421a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project * libffi-1.20, this is not the case.) 422a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project */ 423a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 424a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void 425a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, 426a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned *, void (*fn)(void)); 427a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 428a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 429a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectextern void 430a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, 431a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project unsigned, unsigned *, void (*fn)(void)); 432a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif /* X86_WIN32 */ 433a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 434a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectvoid 435a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) 436a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{ 437a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project extended_cif ecif; 438a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project void **avalue = (void **)fake_avalue; 439a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 440a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.cif = cif; 441a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.avalue = avalue; 442a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 443a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* If the return value is a struct and we don't have a return */ 444a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project /* value address then we need to make one */ 445a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 446a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project if ((rvalue == NULL) && 447a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project (cif->rtype->type == FFI_TYPE_STRUCT)) 448a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 449a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = alloca(cif->rtype->size); 450a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 451a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project else 452a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue = rvalue; 453a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 454a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 455a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project switch (cif->abi) 456a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project { 457a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_SYSV: 458a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, 459a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue, fn); 460a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 461a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef X86_WIN32 462a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project case FFI_STDCALL: 463a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, 464a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project ecif.rvalue, fn); 465a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 466a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif /* X86_WIN32 */ 467a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project default: 468a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project FFI_ASSERT(0); 469a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project break; 470a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project } 471a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} 472a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 473a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif 474a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project 475a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif /* __x86_64__ */ 476