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 ----------------------------------------------------------------------- */
33 #include <ffi_common.h>
37 /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
38 all further uses in this file will refer to the 80-bit type. */
39 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
40 # if FFI_TYPE_LONGDOUBLE != 4
41 # error FFI_TYPE_LONGDOUBLE out of date
44 # undef FFI_TYPE_LONGDOUBLE
45 # define FFI_TYPE_LONGDOUBLE 4
48 #if defined(__GNUC__) && !defined(__declspec)
49 # define __declspec(x) __attribute__((x))
52 /* Perform machine dependent cif processing. */
54 ffi_prep_cif_machdep(ffi_cif
*cif
)
57 int i
, n
, flags
, cabi
= cif
->abi
;
73 switch (cif
->rtype
->type
)
79 flags
= X86_RET_FLOAT
;
82 flags
= X86_RET_DOUBLE
;
84 case FFI_TYPE_LONGDOUBLE
:
85 flags
= X86_RET_LDOUBLE
;
88 flags
= X86_RET_UINT8
;
91 flags
= X86_RET_UINT16
;
94 flags
= X86_RET_SINT8
;
97 flags
= X86_RET_SINT16
;
100 case FFI_TYPE_SINT32
:
101 case FFI_TYPE_UINT32
:
102 case FFI_TYPE_POINTER
:
103 flags
= X86_RET_INT32
;
105 case FFI_TYPE_SINT64
:
106 case FFI_TYPE_UINT64
:
107 flags
= X86_RET_INT64
;
109 case FFI_TYPE_STRUCT
:
111 /* ??? This should be a different ABI rather than an ifdef. */
112 if (cif
->rtype
->size
== 1)
113 flags
= X86_RET_STRUCT_1B
;
114 else if (cif
->rtype
->size
== 2)
115 flags
= X86_RET_STRUCT_2B
;
116 else if (cif
->rtype
->size
== 4)
117 flags
= X86_RET_INT32
;
118 else if (cif
->rtype
->size
== 8)
119 flags
= X86_RET_INT64
;
130 flags
= X86_RET_STRUCTARG
;
133 flags
= X86_RET_STRUCTPOP
;
136 /* Allocate space for return value pointer. */
137 bytes
+= ALIGN (sizeof(void*), FFI_SIZEOF_ARG
);
140 case FFI_TYPE_COMPLEX
:
141 switch (cif
->rtype
->elements
[0]->type
)
143 case FFI_TYPE_DOUBLE
:
144 case FFI_TYPE_LONGDOUBLE
:
145 case FFI_TYPE_SINT64
:
146 case FFI_TYPE_UINT64
:
150 case FFI_TYPE_SINT32
:
151 case FFI_TYPE_UINT32
:
152 flags
= X86_RET_INT64
;
154 case FFI_TYPE_SINT16
:
155 case FFI_TYPE_UINT16
:
156 flags
= X86_RET_INT32
;
160 flags
= X86_RET_STRUCT_2B
;
163 return FFI_BAD_TYPEDEF
;
167 return FFI_BAD_TYPEDEF
;
171 for (i
= 0, n
= cif
->nargs
; i
< n
; i
++)
173 ffi_type
*t
= cif
->arg_types
[i
];
175 bytes
= ALIGN (bytes
, t
->alignment
);
176 bytes
+= ALIGN (t
->size
, FFI_SIZEOF_ARG
);
178 cif
->bytes
= ALIGN (bytes
, 16);
184 extend_basic_type(void *arg
, int type
)
189 return *(SINT8
*)arg
;
191 return *(UINT8
*)arg
;
192 case FFI_TYPE_SINT16
:
193 return *(SINT16
*)arg
;
194 case FFI_TYPE_UINT16
:
195 return *(UINT16
*)arg
;
197 case FFI_TYPE_SINT32
:
198 case FFI_TYPE_UINT32
:
199 case FFI_TYPE_POINTER
:
201 return *(UINT32
*)arg
;
211 void *retaddr
; /* 4 */
212 void (*fn
)(void); /* 8 */
214 void *rvalue
; /* 16 */
215 unsigned regs
[3]; /* 20-28 */
220 int dir
; /* parameter growth direction */
221 int static_chain
; /* the static chain register used by gcc */
222 int nregs
; /* number of register parameters */
226 static const struct abi_params abi_params
[FFI_LAST_ABI
] = {
227 [FFI_SYSV
] = { 1, R_ECX
, 0 },
228 [FFI_THISCALL
] = { 1, R_EAX
, 1, { R_ECX
} },
229 [FFI_FASTCALL
] = { 1, R_EAX
, 2, { R_ECX
, R_EDX
} },
230 [FFI_STDCALL
] = { 1, R_ECX
, 0 },
231 [FFI_PASCAL
] = { -1, R_ECX
, 0 },
232 /* ??? No defined static chain; gcc does not support REGISTER. */
233 [FFI_REGISTER
] = { -1, R_ECX
, 3, { R_EAX
, R_EDX
, R_ECX
} },
234 [FFI_MS_CDECL
] = { 1, R_ECX
, 0 }
237 extern void ffi_call_i386(struct call_frame
*, char *)
244 ffi_call_int (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
,
245 void **avalue
, void *closure
)
248 struct call_frame
*frame
;
250 ffi_type
**arg_types
;
251 int flags
, cabi
, i
, n
, dir
, narg_reg
;
252 const struct abi_params
*pabi
;
256 pabi
= &abi_params
[cabi
];
266 case X86_RET_LDOUBLE
:
267 case X86_RET_STRUCTPOP
:
268 case X86_RET_STRUCTARG
:
269 /* The float cases need to pop the 387 stack.
270 The struct cases need to pass a valid pointer to the callee. */
271 rsize
= cif
->rtype
->size
;
274 /* We can pretend that the callee returns nothing. */
275 flags
= X86_RET_VOID
;
281 stack
= alloca(bytes
+ sizeof(*frame
) + rsize
);
282 argp
= (dir
< 0 ? stack
+ bytes
: stack
);
283 frame
= (struct call_frame
*)(stack
+ bytes
);
288 frame
->flags
= flags
;
289 frame
->rvalue
= rvalue
;
290 frame
->regs
[pabi
->static_chain
] = (unsigned)closure
;
295 case X86_RET_STRUCTARG
:
296 /* The pointer is passed as the first argument. */
299 frame
->regs
[pabi
->regs
[0]] = (unsigned)rvalue
;
304 case X86_RET_STRUCTPOP
:
305 *(void **)argp
= rvalue
;
306 argp
+= sizeof(void *);
310 arg_types
= cif
->arg_types
;
311 for (i
= 0, n
= cif
->nargs
; i
< n
; i
++)
313 ffi_type
*ty
= arg_types
[i
];
314 void *valp
= avalue
[i
];
318 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
)
320 ffi_arg val
= extend_basic_type (valp
, t
);
322 if (t
!= FFI_TYPE_FLOAT
&& narg_reg
< pabi
->nregs
)
323 frame
->regs
[pabi
->regs
[narg_reg
++]] = val
;
327 *(ffi_arg
*)argp
= val
;
331 *(ffi_arg
*)argp
= val
;
337 size_t za
= ALIGN (z
, FFI_SIZEOF_ARG
);
338 size_t align
= FFI_SIZEOF_ARG
;
340 /* Alignment rules for arguments are quite complex. Vectors and
341 structures with 16 byte alignment get it. Note that long double
342 on Darwin does have 16 byte alignment, and does not get this
343 alignment if passed directly; a structure with a long double
344 inside, however, would get 16 byte alignment. Since libffi does
345 not support vectors, we need non concern ourselves with other
347 if (t
== FFI_TYPE_STRUCT
&& ty
->alignment
>= 16)
352 /* ??? These reverse argument ABIs are probably too old
353 to have cared about alignment. Someone should check. */
355 memcpy (argp
, valp
, z
);
359 argp
= (char *)ALIGN (argp
, align
);
360 memcpy (argp
, valp
, z
);
365 FFI_ASSERT (dir
> 0 || argp
== stack
);
367 ffi_call_i386 (frame
, stack
);
371 ffi_call (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
373 ffi_call_int (cif
, fn
, rvalue
, avalue
, NULL
);
377 ffi_call_go (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
,
378 void **avalue
, void *closure
)
380 ffi_call_int (cif
, fn
, rvalue
, avalue
, closure
);
383 /** private members **/
385 void FFI_HIDDEN
ffi_closure_i386(void);
386 void FFI_HIDDEN
ffi_closure_STDCALL(void);
387 void FFI_HIDDEN
ffi_closure_REGISTER(void);
391 unsigned rettemp
[4]; /* 0 */
392 unsigned regs
[3]; /* 16-24 */
393 ffi_cif
*cif
; /* 28 */
394 void (*fun
)(ffi_cif
*,void*,void**,void*); /* 32 */
395 void *user_data
; /* 36 */
402 ffi_closure_inner (struct closure_frame
*frame
, char *stack
)
404 ffi_cif
*cif
= frame
->cif
;
405 int cabi
, i
, n
, flags
, dir
, narg_reg
;
406 const struct abi_params
*pabi
;
407 ffi_type
**arg_types
;
415 rvalue
= frame
->rettemp
;
416 pabi
= &abi_params
[cabi
];
418 argp
= (dir
< 0 ? stack
+ cif
->bytes
: stack
);
422 case X86_RET_STRUCTARG
:
425 rvalue
= (void *)frame
->regs
[pabi
->regs
[0]];
427 frame
->rettemp
[0] = (unsigned)rvalue
;
431 case X86_RET_STRUCTPOP
:
432 rvalue
= *(void **)argp
;
433 argp
+= sizeof(void *);
434 frame
->rettemp
[0] = (unsigned)rvalue
;
439 avalue
= alloca(sizeof(void *) * n
);
441 arg_types
= cif
->arg_types
;
442 for (i
= 0; i
< n
; ++i
)
444 ffi_type
*ty
= arg_types
[i
];
449 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
)
451 if (t
!= FFI_TYPE_FLOAT
&& narg_reg
< pabi
->nregs
)
452 valp
= &frame
->regs
[pabi
->regs
[narg_reg
++]];
466 size_t za
= ALIGN (z
, FFI_SIZEOF_ARG
);
467 size_t align
= FFI_SIZEOF_ARG
;
469 /* See the comment in ffi_call_int. */
470 if (t
== FFI_TYPE_STRUCT
&& ty
->alignment
>= 16)
475 /* ??? These reverse argument ABIs are probably too old
476 to have cared about alignment. Someone should check. */
482 argp
= (char *)ALIGN (argp
, align
);
491 frame
->fun (cif
, rvalue
, avalue
, frame
->user_data
);
493 if (cabi
== FFI_STDCALL
)
494 return flags
+ (cif
->bytes
<< X86_RET_POP_SHIFT
);
500 ffi_prep_closure_loc (ffi_closure
* closure
,
502 void (*fun
)(ffi_cif
*,void*,void**,void*),
506 char *tramp
= closure
->tramp
;
508 int op
= 0xb8; /* movl imm, %eax */
516 dest
= ffi_closure_i386
;
520 dest
= ffi_closure_STDCALL
;
523 dest
= ffi_closure_REGISTER
;
524 op
= 0x68; /* pushl imm */
529 /* movl or pushl immediate. */
531 *(void **)(tramp
+ 1) = codeloc
;
535 *(unsigned *)(tramp
+ 6) = (unsigned)dest
- ((unsigned)codeloc
+ 10);
539 closure
->user_data
= user_data
;
544 void FFI_HIDDEN
ffi_go_closure_EAX(void);
545 void FFI_HIDDEN
ffi_go_closure_ECX(void);
546 void FFI_HIDDEN
ffi_go_closure_STDCALL(void);
549 ffi_prep_go_closure (ffi_go_closure
* closure
, ffi_cif
* cif
,
550 void (*fun
)(ffi_cif
*,void*,void**,void*))
558 dest
= ffi_go_closure_ECX
;
562 dest
= ffi_go_closure_EAX
;
566 dest
= ffi_go_closure_STDCALL
;
573 closure
->tramp
= dest
;
580 /* ------- Native raw API support -------------------------------- */
584 void FFI_HIDDEN
ffi_closure_raw_SYSV(void);
585 void FFI_HIDDEN
ffi_closure_raw_THISCALL(void);
588 ffi_prep_raw_closure_loc (ffi_raw_closure
*closure
,
590 void (*fun
)(ffi_cif
*,void*,ffi_raw
*,void*),
594 char *tramp
= closure
->tramp
;
598 /* We currently don't support certain kinds of arguments for raw
599 closures. This should be implemented by a separate assembly
600 language routine, since it would require argument processing,
601 something we don't do now for performance. */
602 for (i
= cif
->nargs
-1; i
>= 0; i
--)
603 switch (cif
->arg_types
[i
]->type
)
605 case FFI_TYPE_STRUCT
:
606 case FFI_TYPE_LONGDOUBLE
:
607 return FFI_BAD_TYPEDEF
;
613 dest
= ffi_closure_raw_THISCALL
;
616 dest
= ffi_closure_raw_SYSV
;
622 /* movl imm, %eax. */
624 *(void **)(tramp
+ 1) = codeloc
;
628 *(unsigned *)(tramp
+ 6) = (unsigned)dest
- ((unsigned)codeloc
+ 10);
632 closure
->user_data
= user_data
;
638 ffi_raw_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, ffi_raw
*avalue
)
641 struct call_frame
*frame
;
643 ffi_type
**arg_types
;
644 int flags
, cabi
, i
, n
, narg_reg
;
645 const struct abi_params
*pabi
;
649 pabi
= &abi_params
[cabi
];
658 case X86_RET_LDOUBLE
:
659 case X86_RET_STRUCTPOP
:
660 case X86_RET_STRUCTARG
:
661 /* The float cases need to pop the 387 stack.
662 The struct cases need to pass a valid pointer to the callee. */
663 rsize
= cif
->rtype
->size
;
666 /* We can pretend that the callee returns nothing. */
667 flags
= X86_RET_VOID
;
673 argp
= stack
= alloca(bytes
+ sizeof(*frame
) + rsize
);
674 frame
= (struct call_frame
*)(stack
+ bytes
);
679 frame
->flags
= flags
;
680 frame
->rvalue
= rvalue
;
685 case X86_RET_STRUCTARG
:
686 /* The pointer is passed as the first argument. */
689 frame
->regs
[pabi
->regs
[0]] = (unsigned)rvalue
;
694 case X86_RET_STRUCTPOP
:
695 *(void **)argp
= rvalue
;
696 argp
+= sizeof(void *);
697 bytes
-= sizeof(void *);
701 arg_types
= cif
->arg_types
;
702 for (i
= 0, n
= cif
->nargs
; narg_reg
< pabi
->nregs
&& i
< n
; i
++)
704 ffi_type
*ty
= arg_types
[i
];
708 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
&& t
!= FFI_TYPE_FLOAT
)
710 ffi_arg val
= extend_basic_type (avalue
, t
);
711 frame
->regs
[pabi
->regs
[narg_reg
++]] = val
;
716 memcpy (argp
, avalue
, z
);
717 z
= ALIGN (z
, FFI_SIZEOF_ARG
);
724 memcpy (argp
, avalue
, bytes
);
726 ffi_call_i386 (frame
, stack
);
728 #endif /* !FFI_NO_RAW_API */
729 #endif /* !__x86_64__ */