1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2011 Timothy Wall
3 Copyright (c) 2011 Plausible Labs Cooperative, Inc.
4 Copyright (c) 2011 Anthony Green
5 Copyright (c) 2011 Free Software Foundation
6 Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
8 ARM Foreign Function Interface
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 ``Software''), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice shall be included
19 in all copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 DEALINGS IN THE SOFTWARE.
29 ----------------------------------------------------------------------- */
31 #if defined(__arm__) || defined(_M_ARM)
32 #include <fficonfig.h>
34 #include <ffi_common.h>
40 #if defined(_MSC_VER) && defined(_M_ARM)
41 #define WIN32_LEAN_AND_MEAN
45 #if FFI_EXEC_TRAMPOLINE_TABLE
48 #include <mach/machine/vm_param.h>
53 extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
55 extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
59 #if defined(__FreeBSD__) && defined(__arm__)
60 #include <sys/types.h>
61 #include <machine/sysarch.h>
64 /* Forward declares. */
65 static int vfp_type_p (const ffi_type *);
66 static void layout_vfp_args (ffi_cif *);
69 ffi_align (ffi_type *ty, void *p)
71 /* Align if necessary */
76 alignment = ty->alignment;
80 return (void *) FFI_ALIGN (p, alignment);
84 ffi_put_arg (ffi_type *ty, void *src, void *dst)
91 *(UINT32 *)dst = *(SINT8 *)src;
94 *(UINT32 *)dst = *(UINT8 *)src;
97 *(UINT32 *)dst = *(SINT16 *)src;
100 *(UINT32 *)dst = *(UINT16 *)src;
104 case FFI_TYPE_SINT32:
105 case FFI_TYPE_UINT32:
106 case FFI_TYPE_POINTER:
110 *(UINT32 *)dst = *(UINT32 *)src;
114 // casting a float* to a UINT32* doesn't work on Windows
116 *(uintptr_t *)dst = 0;
117 *(float *)dst = *(float *)src;
121 case FFI_TYPE_SINT64:
122 case FFI_TYPE_UINT64:
123 case FFI_TYPE_DOUBLE:
124 *(UINT64 *)dst = *(UINT64 *)src;
127 case FFI_TYPE_STRUCT:
128 case FFI_TYPE_COMPLEX:
129 memcpy (dst, src, z);
136 return FFI_ALIGN (z, 4);
139 /* ffi_prep_args is called once stack space has been allocated
140 for the function's arguments.
142 The vfp_space parameter is the load area for VFP regs, the return
143 value is cif->vfp_used (word bitset of VFP regs used for passing
144 arguments). These are only used for the VFP hard-float ABI.
147 ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,
148 void **avalue, char *argp)
150 ffi_type **arg_types = cif->arg_types;
153 if (flags == ARM_TYPE_STRUCT)
155 *(void **) argp = rvalue;
159 for (i = 0, n = cif->nargs; i < n; i++)
161 ffi_type *ty = arg_types[i];
162 argp = ffi_align (ty, argp);
163 argp += ffi_put_arg (ty, avalue[i], argp);
168 ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
169 void **avalue, char *stack, char *vfp_space)
171 ffi_type **arg_types = cif->arg_types;
173 char *argp, *regp, *eo_regp;
175 char done_with_regs = 0;
177 /* The first 4 words on the stack are used for values
178 passed in core registers. */
180 eo_regp = argp = regp + 16;
182 /* If the function returns an FFI_TYPE_STRUCT in memory,
183 that address is passed in r0 to the function. */
184 if (flags == ARM_TYPE_STRUCT)
186 *(void **) regp = rvalue;
190 for (i = 0, n = cif->nargs; i < n; i++)
192 ffi_type *ty = arg_types[i];
194 int is_vfp_type = vfp_type_p (ty);
196 /* Allocated in VFP registers. */
197 if (vi < cif->vfp_nargs && is_vfp_type)
199 char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;
200 ffi_put_arg (ty, a, vfp_slot);
203 /* Try allocating in core registers. */
204 else if (!done_with_regs && !is_vfp_type)
206 char *tregp = ffi_align (ty, regp);
207 size_t size = ty->size;
208 size = (size < 4) ? 4 : size; // pad
209 /* Check if there is space left in the aligned register
210 area to place the argument. */
211 if (tregp + size <= eo_regp)
213 regp = tregp + ffi_put_arg (ty, a, tregp);
214 done_with_regs = (regp == argp);
215 // ensure we did not write into the stack area
216 FFI_ASSERT (regp <= argp);
219 /* In case there are no arguments in the stack area yet,
220 the argument is passed in the remaining core registers
222 else if (!stack_used)
226 argp = tregp + ffi_put_arg (ty, a, tregp);
227 FFI_ASSERT (eo_regp < argp);
231 /* Base case, arguments are passed on the stack */
233 argp = ffi_align (ty, argp);
234 argp += ffi_put_arg (ty, a, argp);
238 /* Perform machine dependent cif processing */
239 ffi_status FFI_HIDDEN
240 ffi_prep_cif_machdep (ffi_cif *cif)
242 int flags = 0, cabi = cif->abi;
243 size_t bytes = cif->bytes;
245 /* Map out the register placements of VFP register args. The VFP
246 hard-float calling conventions are slightly more sophisticated
247 than the base calling conventions, so we do it here instead of
248 in ffi_prep_args(). */
250 layout_vfp_args (cif);
252 /* Set the return type flag */
253 switch (cif->rtype->type)
256 flags = ARM_TYPE_VOID;
262 case FFI_TYPE_UINT16:
263 case FFI_TYPE_SINT16:
264 case FFI_TYPE_UINT32:
265 case FFI_TYPE_SINT32:
266 case FFI_TYPE_POINTER:
267 flags = ARM_TYPE_INT;
270 case FFI_TYPE_SINT64:
271 case FFI_TYPE_UINT64:
272 flags = ARM_TYPE_INT64;
276 flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);
278 case FFI_TYPE_DOUBLE:
279 flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);
282 case FFI_TYPE_STRUCT:
283 case FFI_TYPE_COMPLEX:
286 int h = vfp_type_p (cif->rtype);
288 flags = ARM_TYPE_VFP_N;
289 if (h == 0x100 + FFI_TYPE_FLOAT)
290 flags = ARM_TYPE_VFP_S;
291 if (h == 0x100 + FFI_TYPE_DOUBLE)
292 flags = ARM_TYPE_VFP_D;
297 /* A Composite Type not larger than 4 bytes is returned in r0.
298 A Composite Type larger than 4 bytes, or whose size cannot
299 be determined statically ... is stored in memory at an
300 address passed [in r0]. */
301 if (cif->rtype->size <= 4)
302 flags = ARM_TYPE_INT;
305 flags = ARM_TYPE_STRUCT;
314 /* Round the stack up to a multiple of 8 bytes. This isn't needed
315 everywhere, but it is on some platforms, and it doesn't harm anything
316 when it isn't needed. */
317 bytes = FFI_ALIGN (bytes, 8);
319 /* Minimum stack space is the 4 register arguments that we pop. */
329 /* Perform machine dependent cif processing for variadic calls */
330 ffi_status FFI_HIDDEN
331 ffi_prep_cif_machdep_var (ffi_cif * cif,
332 unsigned int nfixedargs, unsigned int ntotalargs)
334 /* VFP variadic calls actually use the SYSV ABI */
335 if (cif->abi == FFI_VFP)
338 return ffi_prep_cif_machdep (cif);
341 /* Prototypes for assembly functions, in sysv.S. */
352 extern void ffi_call_SYSV (void *stack, struct call_frame *,
353 void (*fn) (void)) FFI_HIDDEN;
354 extern void ffi_call_VFP (void *vfp_space, struct call_frame *,
355 void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;
358 ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,
359 void **avalue, void *closure)
361 int flags = cif->flags;
362 ffi_type *rtype = cif->rtype;
363 size_t bytes, rsize, vfp_size;
364 char *stack, *vfp_space, *new_rvalue;
365 struct call_frame *frame;
370 /* If the return value is a struct and we don't have a return
371 value address then we need to make one. Otherwise the return
372 value is in registers and we can ignore them. */
373 if (flags == ARM_TYPE_STRUCT)
376 flags = ARM_TYPE_VOID;
378 else if (flags == ARM_TYPE_VFP_N)
380 /* Largest case is double x 4. */
383 else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)
387 vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);
390 stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);
399 frame = (struct call_frame *)(stack + bytes);
403 new_rvalue = (void *)(frame + 1);
405 frame->rvalue = new_rvalue;
406 frame->flags = flags;
407 frame->closure = closure;
411 ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);
412 ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);
416 ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);
417 ffi_call_SYSV (stack, frame, fn);
420 if (rvalue && rvalue != new_rvalue)
421 memcpy (rvalue, new_rvalue, rtype->size);
425 ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
427 ffi_call_int (cif, fn, rvalue, avalue, NULL);
430 #ifdef FFI_GO_CLOSURES
432 ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
433 void **avalue, void *closure)
435 ffi_call_int (cif, fn, rvalue, avalue, closure);
440 ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
441 char *argp, void **avalue)
443 ffi_type **arg_types = cif->arg_types;
446 if (cif->flags == ARM_TYPE_STRUCT)
448 rvalue = *(void **) argp;
453 if (cif->rtype->size && cif->rtype->size < 4)
454 *(uint32_t *) rvalue = 0;
457 for (i = 0, n = cif->nargs; i < n; i++)
459 ffi_type *ty = arg_types[i];
462 argp = ffi_align (ty, argp);
463 avalue[i] = (void *) argp;
471 ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,
472 char *vfp_space, void **avalue)
474 ffi_type **arg_types = cif->arg_types;
476 char *argp, *regp, *eo_regp;
477 char done_with_regs = 0;
481 eo_regp = argp = regp + 16;
483 if (cif->flags == ARM_TYPE_STRUCT)
485 rvalue = *(void **) regp;
489 for (i = 0, n = cif->nargs; i < n; i++)
491 ffi_type *ty = arg_types[i];
492 int is_vfp_type = vfp_type_p (ty);
495 if (vi < cif->vfp_nargs && is_vfp_type)
497 avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;
500 else if (!done_with_regs && !is_vfp_type)
502 char *tregp = ffi_align (ty, regp);
504 z = (z < 4) ? 4 : z; // pad
506 /* If the arguments either fits into the registers or uses registers
507 and stack, while we haven't read other things from the stack */
508 if (tregp + z <= eo_regp || !stack_used)
510 /* Because we're little endian, this is what it turns into. */
511 avalue[i] = (void *) tregp;
514 /* If we read past the last core register, make sure we
515 have not read from the stack before and continue
516 reading after regp. */
519 FFI_ASSERT (!stack_used);
532 argp = ffi_align (ty, argp);
533 avalue[i] = (void *) argp;
542 char vfp_space[8*8] __attribute__((aligned(8)));
548 ffi_closure_inner_SYSV (ffi_cif *cif,
549 void (*fun) (ffi_cif *, void *, void **, void *),
551 struct closure_frame *frame)
553 void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
554 void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,
555 frame->argp, avalue);
556 fun (cif, rvalue, avalue, user_data);
561 ffi_closure_inner_VFP (ffi_cif *cif,
562 void (*fun) (ffi_cif *, void *, void **, void *),
564 struct closure_frame *frame)
566 void **avalue = (void **) alloca (cif->nargs * sizeof (void *));
567 void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,
568 frame->vfp_space, avalue);
569 fun (cif, rvalue, avalue, user_data);
573 void ffi_closure_SYSV (void) FFI_HIDDEN;
574 void ffi_closure_VFP (void) FFI_HIDDEN;
575 #if defined(FFI_EXEC_STATIC_TRAMP)
576 void ffi_closure_SYSV_alt (void) FFI_HIDDEN;
577 void ffi_closure_VFP_alt (void) FFI_HIDDEN;
580 #ifdef FFI_GO_CLOSURES
581 void ffi_go_closure_SYSV (void) FFI_HIDDEN;
582 void ffi_go_closure_VFP (void) FFI_HIDDEN;
585 /* the cif must already be prep'ed */
587 #if defined(__FreeBSD__) && defined(__arm__)
588 #define __clear_cache(start, end) do { \
589 struct arm_sync_icache_args ua; \
591 ua.addr = (uintptr_t)(start); \
592 ua.len = (char *)(end) - (char *)start; \
593 sysarch(ARM_SYNC_ICACHE, &ua); \
598 ffi_prep_closure_loc (ffi_closure * closure,
600 void (*fun) (ffi_cif *, void *, void **, void *),
601 void *user_data, void *codeloc)
603 void (*closure_func) (void) = ffi_closure_SYSV;
605 if (cif->abi == FFI_VFP)
607 /* We only need take the vfp path if there are vfp arguments. */
609 closure_func = ffi_closure_VFP;
611 else if (cif->abi != FFI_SYSV)
614 #if FFI_EXEC_TRAMPOLINE_TABLE
615 void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);
617 config[1] = closure_func;
620 #if defined(FFI_EXEC_STATIC_TRAMP)
621 if (ffi_tramp_is_present(closure))
623 /* Initialize the static trampoline's parameters. */
624 if (closure_func == ffi_closure_SYSV)
625 closure_func = ffi_closure_SYSV_alt;
627 closure_func = ffi_closure_VFP_alt;
628 ffi_tramp_set_parms (closure->ftramp, closure_func, closure);
633 /* Initialize the dynamic trampoline. */
635 memcpy(closure->tramp, ffi_arm_trampoline, 8);
637 // cast away function type so MSVC doesn't set the lower bit of the function pointer
638 memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
641 #if defined (__QNX__)
642 msync(closure->tramp, 8, 0x1000000); /* clear data map */
643 msync(codeloc, 8, 0x1000000); /* clear insn map */
644 #elif defined(_MSC_VER)
645 FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
647 __clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
648 __clear_cache(codeloc, codeloc + 8); /* clear insn map */
651 *(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
653 *(void (**)(void))(closure->tramp + 8) = closure_func;
660 closure->user_data = user_data;
665 #ifdef FFI_GO_CLOSURES
667 ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
668 void (*fun) (ffi_cif *, void *, void **, void *))
670 void (*closure_func) (void) = ffi_go_closure_SYSV;
672 if (cif->abi == FFI_VFP)
674 /* We only need take the vfp path if there are vfp arguments. */
676 closure_func = ffi_go_closure_VFP;
678 else if (cif->abi != FFI_SYSV)
681 closure->tramp = closure_func;
689 /* Below are routines for VFP hard-float support. */
691 /* A subroutine of vfp_type_p. Given a structure type, return the type code
692 of the first non-structure element. Recurse for structure elements.
693 Return -1 if the structure is in fact empty, i.e. no nested elements. */
696 is_hfa0 (const ffi_type *ty)
698 ffi_type **elements = ty->elements;
701 if (elements != NULL)
702 for (i = 0; elements[i]; ++i)
704 ret = elements[i]->type;
705 if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)
707 ret = is_hfa0 (elements[i]);
717 /* A subroutine of vfp_type_p. Given a structure type, return true if all
718 of the non-structure elements are the same as CANDIDATE. */
721 is_hfa1 (const ffi_type *ty, int candidate)
723 ffi_type **elements = ty->elements;
726 if (elements != NULL)
727 for (i = 0; elements[i]; ++i)
729 int t = elements[i]->type;
730 if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
732 if (!is_hfa1 (elements[i], candidate))
735 else if (t != candidate)
742 /* Determine if TY is an homogenous floating point aggregate (HFA).
743 That is, a structure consisting of 1 to 4 members of all the same type,
744 where that type is a floating point scalar.
746 Returns non-zero iff TY is an HFA. The result is an encoded value where
747 bits 0-7 contain the type code, and bits 8-10 contain the element count. */
750 vfp_type_p (const ffi_type *ty)
754 size_t size, ele_count;
756 /* Quickest tests first. */
757 candidate = ty->type;
763 case FFI_TYPE_DOUBLE:
766 case FFI_TYPE_COMPLEX:
767 candidate = ty->elements[0]->type;
768 if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)
772 case FFI_TYPE_STRUCT:
776 /* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */
778 if (size < 4 || size > 32)
781 /* Find the type of the first non-structure member. */
782 elements = ty->elements;
783 candidate = elements[0]->type;
784 if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)
788 candidate = is_hfa0 (elements[i]);
794 /* If the first member is not a floating point type, it's not an HFA.
795 Also quickly re-check the size of the structure. */
799 ele_count = size / sizeof(float);
800 if (size != ele_count * sizeof(float))
803 case FFI_TYPE_DOUBLE:
804 ele_count = size / sizeof(double);
805 if (size != ele_count * sizeof(double))
814 /* Finally, make sure that all scalar elements are the same type. */
815 for (i = 0; elements[i]; ++i)
817 int t = elements[i]->type;
818 if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)
820 if (!is_hfa1 (elements[i], candidate))
823 else if (t != candidate)
827 /* All tests succeeded. Encode the result. */
829 return (ele_count << 8) | candidate;
833 place_vfp_arg (ffi_cif *cif, int h)
835 unsigned short reg = cif->vfp_reg_free;
836 int align = 1, nregs = h >> 8;
838 if ((h & 0xff) == FFI_TYPE_DOUBLE)
839 align = 2, nregs *= 2;
841 /* Align register number. */
842 if ((reg & 1) && align == 2)
845 while (reg + nregs <= 16)
848 for (s = reg; s < reg + nregs; s++)
850 new_used |= (1 << s);
851 if (cif->vfp_used & (1 << s))
857 /* Found regs to allocate. */
858 cif->vfp_used |= new_used;
859 cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
861 /* Update vfp_reg_free. */
862 if (cif->vfp_used & (1 << cif->vfp_reg_free))
865 while (cif->vfp_used & (1 << reg))
867 cif->vfp_reg_free = reg;
872 // done, mark all regs as used
873 cif->vfp_reg_free = 16;
874 cif->vfp_used = 0xFFFF;
879 layout_vfp_args (ffi_cif * cif)
882 /* Init VFP fields */
885 cif->vfp_reg_free = 0;
886 memset (cif->vfp_args, -1, 16); /* Init to -1. */
888 for (i = 0; i < cif->nargs; i++)
890 int h = vfp_type_p (cif->arg_types[i]);
891 if (h && place_vfp_arg (cif, h) == 1)
896 #if defined(FFI_EXEC_STATIC_TRAMP)
898 ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
900 extern void *trampoline_code_table;
902 *tramp_size = ARM_TRAMP_SIZE;
903 *map_size = ARM_TRAMP_MAP_SIZE;
904 return &trampoline_code_table;
908 #endif /* __arm__ or _M_ARM */