1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
3 Copyright (c) 2002 Ranjit Mathew
4 Copyright (c) 2002 Bo Thorsen
5 Copyright (c) 2002 Roger Sayle
6 Copyright (C) 2008, 2010 Free Software Foundation, Inc.
8 x86 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(__x86_64__) || defined(_WIN64)
38 #include <ffi_common.h>
42 /* ffi_prep_args is called by the assembly routine once stack space
43 has been allocated for the function's arguments */
45 void ffi_prep_args(char *stack
, extended_cif
*ecif
)
47 register unsigned int i
;
48 register void **p_argv
;
50 register ffi_type
**p_arg
;
52 size_t p_stack_args
[2];
53 void *p_stack_data
[2];
55 int stack_args_count
= 0;
56 int cabi
= ecif
->cif
->abi
;
61 if (ecif
->cif
->flags
== FFI_TYPE_STRUCT
63 && (ecif
->cif
->rtype
->size
!= 1 && ecif
->cif
->rtype
->size
!= 2
64 && ecif
->cif
->rtype
->size
!= 4 && ecif
->cif
->rtype
->size
!= 8)
68 *(void **) argp
= ecif
->rvalue
;
70 /* For fastcall/thiscall this is first register-passed
72 if (cabi
== FFI_THISCALL
|| cabi
== FFI_FASTCALL
)
74 p_stack_args
[stack_args_count
] = sizeof (void*);
75 p_stack_data
[stack_args_count
] = argp
;
79 argp
+= sizeof(void*);
82 p_argv
= ecif
->avalue
;
84 for (i
= ecif
->cif
->nargs
, p_arg
= ecif
->cif
->arg_types
;
90 /* Align if necessary */
91 if ((sizeof(void*) - 1) & (size_t) argp
)
92 argp
= (char *) ALIGN(argp
, sizeof(void*));
96 if (z
> sizeof(ffi_arg
)
97 || ((*p_arg
)->type
== FFI_TYPE_STRUCT
98 && (z
!= 1 && z
!= 2 && z
!= 4 && z
!= 8))
99 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
100 || ((*p_arg
)->type
== FFI_TYPE_LONGDOUBLE
)
105 *(void **)argp
= *p_argv
;
107 else if ((*p_arg
)->type
== FFI_TYPE_FLOAT
)
109 memcpy(argp
, *p_argv
, z
);
113 if (z
< sizeof(ffi_arg
))
116 switch ((*p_arg
)->type
)
119 *(ffi_sarg
*) argp
= (ffi_sarg
)*(SINT8
*)(* p_argv
);
123 *(ffi_arg
*) argp
= (ffi_arg
)*(UINT8
*)(* p_argv
);
126 case FFI_TYPE_SINT16
:
127 *(ffi_sarg
*) argp
= (ffi_sarg
)*(SINT16
*)(* p_argv
);
130 case FFI_TYPE_UINT16
:
131 *(ffi_arg
*) argp
= (ffi_arg
)*(UINT16
*)(* p_argv
);
134 case FFI_TYPE_SINT32
:
135 *(ffi_sarg
*) argp
= (ffi_sarg
)*(SINT32
*)(* p_argv
);
138 case FFI_TYPE_UINT32
:
139 *(ffi_arg
*) argp
= (ffi_arg
)*(UINT32
*)(* p_argv
);
142 case FFI_TYPE_STRUCT
:
143 *(ffi_arg
*) argp
= *(ffi_arg
*)(* p_argv
);
152 memcpy(argp
, *p_argv
, z
);
156 /* For thiscall/fastcall convention register-passed arguments
157 are the first two none-floating-point arguments with a size
158 smaller or equal to sizeof (void*). */
159 if ((cabi
== FFI_THISCALL
&& stack_args_count
< 1)
160 || (cabi
== FFI_FASTCALL
&& stack_args_count
< 2))
163 && ((*p_arg
)->type
!= FFI_TYPE_FLOAT
164 && (*p_arg
)->type
!= FFI_TYPE_STRUCT
))
166 p_stack_args
[stack_args_count
] = z
;
167 p_stack_data
[stack_args_count
] = argp
;
174 argp
+= (z
+ sizeof(void*) - 1) & ~(sizeof(void*) - 1);
181 /* We need to move the register-passed arguments for thiscall/fastcall
182 on top of stack, so that those can be moved to registers ecx/edx by
184 if (stack_args_count
> 0)
186 size_t zz
= (p_stack_args
[0] + 3) & ~3;
189 /* Move first argument to top-stack position. */
190 if (p_stack_data
[0] != argp2
)
193 memcpy (h
, p_stack_data
[0], zz
);
194 memmove (argp2
+ zz
, argp2
,
195 (size_t) ((char *) p_stack_data
[0] - (char*)argp2
));
196 memcpy (argp2
, h
, zz
);
202 stack_args_count
= 0;
204 /* If we have a second argument, then move it on top
205 after the first one. */
206 if (stack_args_count
> 0 && p_stack_data
[1] != argp2
)
208 zz
= p_stack_args
[1];
212 memcpy (h
, p_stack_data
[1], zz
);
213 memmove (argp2
+ zz
, argp2
, (size_t) ((char*) p_stack_data
[1] - (char*)argp2
));
214 memcpy (argp2
, h
, zz
);
221 /* Perform machine dependent cif processing */
222 ffi_status
ffi_prep_cif_machdep(ffi_cif
*cif
)
227 /* Set the return type flag */
228 switch (cif
->rtype
->type
)
231 #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
233 case FFI_TYPE_UINT16
:
235 case FFI_TYPE_SINT16
:
238 case FFI_TYPE_UINT32
:
239 case FFI_TYPE_SINT32
:
241 case FFI_TYPE_SINT64
:
243 case FFI_TYPE_DOUBLE
:
245 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
246 case FFI_TYPE_LONGDOUBLE
:
249 cif
->flags
= (unsigned) cif
->rtype
->type
;
252 case FFI_TYPE_UINT64
:
254 case FFI_TYPE_POINTER
:
256 cif
->flags
= FFI_TYPE_SINT64
;
259 case FFI_TYPE_STRUCT
:
261 if (cif
->rtype
->size
== 1)
263 cif
->flags
= FFI_TYPE_SMALL_STRUCT_1B
; /* same as char size */
265 else if (cif
->rtype
->size
== 2)
267 cif
->flags
= FFI_TYPE_SMALL_STRUCT_2B
; /* same as short size */
269 else if (cif
->rtype
->size
== 4)
272 cif
->flags
= FFI_TYPE_SMALL_STRUCT_4B
;
274 cif
->flags
= FFI_TYPE_INT
; /* same as int type */
277 else if (cif
->rtype
->size
== 8)
279 cif
->flags
= FFI_TYPE_SINT64
; /* same as int64 type */
284 cif
->flags
= FFI_TYPE_STRUCT
;
285 /* allocate space for return value pointer */
286 cif
->bytes
+= ALIGN(sizeof(void*), FFI_SIZEOF_ARG
);
292 cif
->flags
= FFI_TYPE_SINT64
;
295 cif
->flags
= FFI_TYPE_SINT32
;
297 cif
->flags
= FFI_TYPE_INT
;
302 for (ptr
= cif
->arg_types
, i
= cif
->nargs
; i
> 0; i
--, ptr
++)
304 if (((*ptr
)->alignment
- 1) & cif
->bytes
)
305 cif
->bytes
= ALIGN(cif
->bytes
, (*ptr
)->alignment
);
306 cif
->bytes
+= ALIGN((*ptr
)->size
, FFI_SIZEOF_ARG
);
310 /* ensure space for storing four registers */
311 cif
->bytes
+= 4 * sizeof(ffi_arg
);
315 cif
->bytes
= (cif
->bytes
+ 15) & ~0xF;
323 ffi_call_win64(void (*)(char *, extended_cif
*), extended_cif
*,
324 unsigned, unsigned, unsigned *, void (*fn
)(void));
325 #elif defined(X86_WIN32)
327 ffi_call_win32(void (*)(char *, extended_cif
*), extended_cif
*,
328 unsigned, unsigned, unsigned, unsigned *, void (*fn
)(void));
330 extern void ffi_call_SYSV(void (*)(char *, extended_cif
*), extended_cif
*,
331 unsigned, unsigned, unsigned *, void (*fn
)(void));
334 void ffi_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
339 ecif
.avalue
= avalue
;
341 /* If the return value is a struct and we don't have a return */
342 /* value address then we need to make one */
346 && cif
->flags
== FFI_TYPE_STRUCT
347 && cif
->rtype
->size
!= 1 && cif
->rtype
->size
!= 2
348 && cif
->rtype
->size
!= 4 && cif
->rtype
->size
!= 8)
350 ecif
.rvalue
= alloca((cif
->rtype
->size
+ 0xF) & ~0xF);
354 && cif
->flags
== FFI_TYPE_STRUCT
)
356 ecif
.rvalue
= alloca(cif
->rtype
->size
);
360 ecif
.rvalue
= rvalue
;
368 /* Make copies of all struct arguments
369 NOTE: not sure if responsibility should be here or in caller */
371 for (i
=0; i
< cif
->nargs
;i
++) {
372 size_t size
= cif
->arg_types
[i
]->size
;
373 if ((cif
->arg_types
[i
]->type
== FFI_TYPE_STRUCT
374 && (size
!= 1 && size
!= 2 && size
!= 4 && size
!= 8))
375 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
376 || cif
->arg_types
[i
]->type
== FFI_TYPE_LONGDOUBLE
380 void *local
= alloca(size
);
381 memcpy(local
, avalue
[i
], size
);
385 ffi_call_win64(ffi_prep_args
, &ecif
, cif
->bytes
,
386 cif
->flags
, ecif
.rvalue
, fn
);
389 #elif defined(X86_WIN32)
392 ffi_call_win32(ffi_prep_args
, &ecif
, cif
->abi
, cif
->bytes
, cif
->flags
,
398 unsigned int abi
= cif
->abi
;
399 unsigned int i
, passed_regs
= 0;
401 if (cif
->flags
== FFI_TYPE_STRUCT
)
404 for (i
=0; i
< cif
->nargs
&& passed_regs
< 2;i
++)
408 if (cif
->arg_types
[i
]->type
== FFI_TYPE_FLOAT
409 || cif
->arg_types
[i
]->type
== FFI_TYPE_STRUCT
)
411 sz
= (cif
->arg_types
[i
]->size
+ 3) & ~3;
412 if (sz
== 0 || sz
> 4)
416 if (passed_regs
< 2 && abi
== FFI_FASTCALL
)
418 if (passed_regs
< 1 && abi
== FFI_THISCALL
)
420 ffi_call_win32(ffi_prep_args
, &ecif
, abi
, cif
->bytes
, cif
->flags
,
426 ffi_call_SYSV(ffi_prep_args
, &ecif
, cif
->bytes
, cif
->flags
, ecif
.rvalue
,
437 /** private members **/
439 /* The following __attribute__((regparm(1))) decorations will have no effect
440 on MSVC - standard cdecl convention applies. */
441 static void ffi_prep_incoming_args_SYSV (char *stack
, void **ret
,
442 void** args
, ffi_cif
* cif
);
443 void FFI_HIDDEN
ffi_closure_SYSV (ffi_closure
*)
444 __attribute__ ((regparm(1)));
445 unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (ffi_closure
*, void **, void *)
446 __attribute__ ((regparm(1)));
447 void FFI_HIDDEN
ffi_closure_raw_SYSV (ffi_raw_closure
*)
448 __attribute__ ((regparm(1)));
450 void FFI_HIDDEN
ffi_closure_STDCALL (ffi_closure
*)
451 __attribute__ ((regparm(1)));
452 void FFI_HIDDEN
ffi_closure_THISCALL (ffi_closure
*)
453 __attribute__ ((regparm(1)));
456 void FFI_HIDDEN
ffi_closure_win64 (ffi_closure
*);
459 /* This function is jumped to by the trampoline */
463 ffi_closure_win64_inner (ffi_closure
*closure
, void *args
) {
467 void *resp
= &result
;
470 arg_area
= (void**) alloca (cif
->nargs
* sizeof (void*));
472 /* this call will initialize ARG_AREA, such that each
473 * element in that array points to the corresponding
474 * value on the stack; and if the function returns
475 * a structure, it will change RESP to point to the
476 * structure return address. */
478 ffi_prep_incoming_args_SYSV(args
, &resp
, arg_area
, cif
);
480 (closure
->fun
) (cif
, resp
, arg_area
, closure
->user_data
);
482 /* The result is returned in rax. This does the right thing for
483 result types except for floats; we have to 'mov xmm0, rax' in the
484 caller to correct this.
485 TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
487 return cif
->rtype
->size
> sizeof(void *) ? resp
: *(void **)resp
;
491 unsigned int FFI_HIDDEN
__attribute__ ((regparm(1)))
492 ffi_closure_SYSV_inner (ffi_closure
*closure
, void **respp
, void *args
)
494 /* our various things... */
499 arg_area
= (void**) alloca (cif
->nargs
* sizeof (void*));
501 /* this call will initialize ARG_AREA, such that each
502 * element in that array points to the corresponding
503 * value on the stack; and if the function returns
504 * a structure, it will change RESP to point to the
505 * structure return address. */
507 ffi_prep_incoming_args_SYSV(args
, respp
, arg_area
, cif
);
509 (closure
->fun
) (cif
, *respp
, arg_area
, closure
->user_data
);
513 #endif /* !X86_WIN64 */
516 ffi_prep_incoming_args_SYSV(char *stack
, void **rvalue
, void **avalue
,
519 register unsigned int i
;
520 register void **p_argv
;
522 register ffi_type
**p_arg
;
527 if (cif
->rtype
->size
> sizeof(ffi_arg
)
528 || (cif
->flags
== FFI_TYPE_STRUCT
529 && (cif
->rtype
->size
!= 1 && cif
->rtype
->size
!= 2
530 && cif
->rtype
->size
!= 4 && cif
->rtype
->size
!= 8))) {
531 *rvalue
= *(void **) argp
;
532 argp
+= sizeof(void *);
535 if ( cif
->flags
== FFI_TYPE_STRUCT
) {
536 *rvalue
= *(void **) argp
;
537 argp
+= sizeof(void *);
543 for (i
= cif
->nargs
, p_arg
= cif
->arg_types
; (i
!= 0); i
--, p_arg
++)
547 /* Align if necessary */
548 if ((sizeof(void*) - 1) & (size_t) argp
) {
549 argp
= (char *) ALIGN(argp
, sizeof(void*));
553 if ((*p_arg
)->size
> sizeof(ffi_arg
)
554 || ((*p_arg
)->type
== FFI_TYPE_STRUCT
555 && ((*p_arg
)->size
!= 1 && (*p_arg
)->size
!= 2
556 && (*p_arg
)->size
!= 4 && (*p_arg
)->size
!= 8)))
559 *p_argv
= *(void **)argp
;
566 /* because we're little endian, this is what it turns into. */
568 *p_argv
= (void*) argp
;
573 argp
+= (z
+ sizeof(void*) - 1) & ~(sizeof(void*) - 1);
582 #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
583 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
584 void* __fun = (void*)(FUN); \
585 void* __ctx = (void*)(CTX); \
586 *(unsigned char*) &__tramp[0] = 0x41; \
587 *(unsigned char*) &__tramp[1] = 0xbb; \
588 *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
589 *(unsigned char*) &__tramp[6] = 0x48; \
590 *(unsigned char*) &__tramp[7] = 0xb8; \
591 *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
592 *(unsigned char *) &__tramp[16] = 0x49; \
593 *(unsigned char *) &__tramp[17] = 0xba; \
594 *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
595 *(unsigned char *) &__tramp[26] = 0x41; \
596 *(unsigned char *) &__tramp[27] = 0xff; \
597 *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
600 /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
602 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
603 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
604 unsigned int __fun = (unsigned int)(FUN); \
605 unsigned int __ctx = (unsigned int)(CTX); \
606 unsigned int __dis = __fun - (__ctx + 10); \
607 *(unsigned char*) &__tramp[0] = 0xb8; \
608 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
609 *(unsigned char *) &__tramp[5] = 0xe9; \
610 *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
613 #define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
614 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
615 unsigned int __fun = (unsigned int)(FUN); \
616 unsigned int __ctx = (unsigned int)(CTX); \
617 unsigned int __dis = __fun - (__ctx + 49); \
618 unsigned short __size = (unsigned short)(SIZE); \
619 *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
620 *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
621 *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
622 *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
623 *(unsigned char*) &__tramp[13] = 0xb8; \
624 *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
625 *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
626 *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
627 *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
628 *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
629 *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
630 *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
631 *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
632 *(unsigned char*) &__tramp[39] = 0xb8; \
633 *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
634 *(unsigned char *) &__tramp[44] = 0xe8; \
635 *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
636 *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
637 *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
640 #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
641 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
642 unsigned int __fun = (unsigned int)(FUN); \
643 unsigned int __ctx = (unsigned int)(CTX); \
644 unsigned int __dis = __fun - (__ctx + 10); \
645 unsigned short __size = (unsigned short)(SIZE); \
646 *(unsigned char*) &__tramp[0] = 0xb8; \
647 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
648 *(unsigned char *) &__tramp[5] = 0xe8; \
649 *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
650 *(unsigned char *) &__tramp[10] = 0xc2; \
651 *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
654 /* the cif must already be prep'ed */
657 ffi_prep_closure_loc (ffi_closure
* closure
,
659 void (*fun
)(ffi_cif
*,void*,void**,void*),
664 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
665 #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
666 if (cif
->abi
== FFI_WIN64
)
668 int mask
= FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
669 FFI_INIT_TRAMPOLINE_WIN64 (&closure
->tramp
[0],
672 /* make sure we can execute here */
675 if (cif
->abi
== FFI_SYSV
)
677 FFI_INIT_TRAMPOLINE (&closure
->tramp
[0],
682 else if (cif
->abi
== FFI_THISCALL
)
684 FFI_INIT_TRAMPOLINE_THISCALL (&closure
->tramp
[0],
685 &ffi_closure_THISCALL
,
689 else if (cif
->abi
== FFI_STDCALL
)
691 FFI_INIT_TRAMPOLINE_STDCALL (&closure
->tramp
[0],
692 &ffi_closure_STDCALL
,
693 (void*)codeloc
, cif
->bytes
);
695 #endif /* X86_WIN32 */
696 #endif /* !X86_WIN64 */
703 closure
->user_data
= user_data
;
709 /* ------- Native raw API support -------------------------------- */
714 ffi_prep_raw_closure_loc (ffi_raw_closure
* closure
,
716 void (*fun
)(ffi_cif
*,void*,ffi_raw
*,void*),
722 if (cif
->abi
!= FFI_SYSV
) {
724 if (cif
->abi
!= FFI_THISCALL
)
729 /* we currently don't support certain kinds of arguments for raw
730 closures. This should be implemented by a separate assembly
731 language routine, since it would require argument processing,
732 something we don't do now for performance. */
734 for (i
= cif
->nargs
-1; i
>= 0; i
--)
736 FFI_ASSERT (cif
->arg_types
[i
]->type
!= FFI_TYPE_STRUCT
);
737 FFI_ASSERT (cif
->arg_types
[i
]->type
!= FFI_TYPE_LONGDOUBLE
);
741 if (cif
->abi
== FFI_SYSV
)
744 FFI_INIT_TRAMPOLINE (&closure
->tramp
[0], &ffi_closure_raw_SYSV
,
748 else if (cif
->abi
== FFI_THISCALL
)
750 FFI_INIT_TRAMPOLINE_THISCALL (&closure
->tramp
[0], &ffi_closure_raw_SYSV
,
751 codeloc
, cif
->bytes
);
755 closure
->user_data
= user_data
;
762 ffi_prep_args_raw(char *stack
, extended_cif
*ecif
)
764 memcpy (stack
, ecif
->avalue
, ecif
->cif
->bytes
);
767 /* we borrow this routine from libffi (it must be changed, though, to
768 * actually call the function passed in the first argument. as of
769 * libffi-1.20, this is not the case.)
773 ffi_raw_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, ffi_raw
*fake_avalue
)
776 void **avalue
= (void **)fake_avalue
;
779 ecif
.avalue
= avalue
;
781 /* If the return value is a struct and we don't have a return */
782 /* value address then we need to make one */
784 if ((rvalue
== NULL
) &&
785 (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
787 ecif
.rvalue
= alloca(cif
->rtype
->size
);
790 ecif
.rvalue
= rvalue
;
798 ffi_call_win32(ffi_prep_args
, &ecif
, cif
->abi
, cif
->bytes
, cif
->flags
,
804 unsigned int abi
= cif
->abi
;
805 unsigned int i
, passed_regs
= 0;
807 if (cif
->flags
== FFI_TYPE_STRUCT
)
810 for (i
=0; i
< cif
->nargs
&& passed_regs
< 2;i
++)
814 if (cif
->arg_types
[i
]->type
== FFI_TYPE_FLOAT
815 || cif
->arg_types
[i
]->type
== FFI_TYPE_STRUCT
)
817 sz
= (cif
->arg_types
[i
]->size
+ 3) & ~3;
818 if (sz
== 0 || sz
> 4)
822 if (passed_regs
< 2 && abi
== FFI_FASTCALL
)
823 cif
->abi
= abi
= FFI_THISCALL
;
824 if (passed_regs
< 1 && abi
== FFI_THISCALL
)
825 cif
->abi
= abi
= FFI_STDCALL
;
826 ffi_call_win32(ffi_prep_args
, &ecif
, abi
, cif
->bytes
, cif
->flags
,
832 ffi_call_SYSV(ffi_prep_args_raw
, &ecif
, cif
->bytes
, cif
->flags
,
844 #endif /* !__x86_64__ || X86_WIN64 */