1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2017 Anthony Green
3 Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
4 Copyright (c) 2002 Ranjit Mathew
5 Copyright (c) 2002 Bo Thorsen
6 Copyright (c) 2002 Roger Sayle
7 Copyright (C) 2008, 2010 Free Software Foundation, Inc.
9 x86 Foreign Function Interface
11 Permission is hereby granted, free of charge, to any person obtaining
12 a copy of this software and associated documentation files (the
13 ``Software''), to deal in the Software without restriction, including
14 without limitation the rights to use, copy, modify, merge, publish,
15 distribute, sublicense, and/or sell copies of the Software, and to
16 permit persons to whom the Software is furnished to do so, subject to
17 the following conditions:
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 DEALINGS IN THE SOFTWARE.
30 ----------------------------------------------------------------------- */
32 #if defined(__i386__) || defined(_M_IX86)
34 #include <ffi_common.h>
40 /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
41 all further uses in this file will refer to the 80-bit type. */
42 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
43 # if FFI_TYPE_LONGDOUBLE != 4
44 # error FFI_TYPE_LONGDOUBLE out of date
47 # undef FFI_TYPE_LONGDOUBLE
48 # define FFI_TYPE_LONGDOUBLE 4
51 #if defined(__GNUC__) && !defined(__declspec)
52 # define __declspec(x) __attribute__((x))
55 #if defined(_MSC_VER) && defined(_M_IX86)
56 /* Stack is not 16-byte aligned on Windows. */
57 #define STACK_ALIGN(bytes) (bytes)
59 #define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
62 /* Perform machine dependent cif processing. */
64 ffi_prep_cif_machdep(ffi_cif
*cif
)
67 int i
, n
, flags
, cabi
= cif
->abi
;
83 switch (cif
->rtype
->type
)
89 flags
= X86_RET_FLOAT
;
92 flags
= X86_RET_DOUBLE
;
94 case FFI_TYPE_LONGDOUBLE
:
95 flags
= X86_RET_LDOUBLE
;
98 flags
= X86_RET_UINT8
;
100 case FFI_TYPE_UINT16
:
101 flags
= X86_RET_UINT16
;
104 flags
= X86_RET_SINT8
;
106 case FFI_TYPE_SINT16
:
107 flags
= X86_RET_SINT16
;
110 case FFI_TYPE_SINT32
:
111 case FFI_TYPE_UINT32
:
112 case FFI_TYPE_POINTER
:
113 flags
= X86_RET_INT32
;
115 case FFI_TYPE_SINT64
:
116 case FFI_TYPE_UINT64
:
117 flags
= X86_RET_INT64
;
119 case FFI_TYPE_STRUCT
:
121 /* ??? This should be a different ABI rather than an ifdef. */
122 if (cif
->rtype
->size
== 1)
123 flags
= X86_RET_STRUCT_1B
;
124 else if (cif
->rtype
->size
== 2)
125 flags
= X86_RET_STRUCT_2B
;
126 else if (cif
->rtype
->size
== 4)
127 flags
= X86_RET_INT32
;
128 else if (cif
->rtype
->size
== 8)
129 flags
= X86_RET_INT64
;
140 flags
= X86_RET_STRUCTARG
;
143 flags
= X86_RET_STRUCTPOP
;
146 /* Allocate space for return value pointer. */
147 bytes
+= FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG
);
150 case FFI_TYPE_COMPLEX
:
151 switch (cif
->rtype
->elements
[0]->type
)
153 case FFI_TYPE_DOUBLE
:
154 case FFI_TYPE_LONGDOUBLE
:
155 case FFI_TYPE_SINT64
:
156 case FFI_TYPE_UINT64
:
160 case FFI_TYPE_SINT32
:
161 case FFI_TYPE_UINT32
:
162 flags
= X86_RET_INT64
;
164 case FFI_TYPE_SINT16
:
165 case FFI_TYPE_UINT16
:
166 flags
= X86_RET_INT32
;
170 flags
= X86_RET_STRUCT_2B
;
173 return FFI_BAD_TYPEDEF
;
177 return FFI_BAD_TYPEDEF
;
181 for (i
= 0, n
= cif
->nargs
; i
< n
; i
++)
183 ffi_type
*t
= cif
->arg_types
[i
];
185 bytes
= FFI_ALIGN (bytes
, t
->alignment
);
186 bytes
+= FFI_ALIGN (t
->size
, FFI_SIZEOF_ARG
);
194 extend_basic_type(void *arg
, int type
)
199 return *(SINT8
*)arg
;
201 return *(UINT8
*)arg
;
202 case FFI_TYPE_SINT16
:
203 return *(SINT16
*)arg
;
204 case FFI_TYPE_UINT16
:
205 return *(UINT16
*)arg
;
207 case FFI_TYPE_SINT32
:
208 case FFI_TYPE_UINT32
:
209 case FFI_TYPE_POINTER
:
211 return *(UINT32
*)arg
;
221 void *retaddr
; /* 4 */
222 void (*fn
)(void); /* 8 */
224 void *rvalue
; /* 16 */
225 unsigned regs
[3]; /* 20-28 */
230 int dir
; /* parameter growth direction */
231 int static_chain
; /* the static chain register used by gcc */
232 int nregs
; /* number of register parameters */
236 static const struct abi_params abi_params
[FFI_LAST_ABI
] = {
237 [FFI_SYSV
] = { 1, R_ECX
, 0 },
238 [FFI_THISCALL
] = { 1, R_EAX
, 1, { R_ECX
} },
239 [FFI_FASTCALL
] = { 1, R_EAX
, 2, { R_ECX
, R_EDX
} },
240 [FFI_STDCALL
] = { 1, R_ECX
, 0 },
241 [FFI_PASCAL
] = { -1, R_ECX
, 0 },
242 /* ??? No defined static chain; gcc does not support REGISTER. */
243 [FFI_REGISTER
] = { -1, R_ECX
, 3, { R_EAX
, R_EDX
, R_ECX
} },
244 [FFI_MS_CDECL
] = { 1, R_ECX
, 0 }
249 #define FFI_DECLARE_FASTCALL __fastcall
251 #define FFI_DECLARE_FASTCALL __declspec(fastcall)
254 #define FFI_DECLARE_FASTCALL
257 extern void FFI_DECLARE_FASTCALL
ffi_call_i386(struct call_frame
*, char *) FFI_HIDDEN
;
259 /* We perform some black magic here to use some of the parent's stack frame in
260 * ffi_call_i386() that breaks with the MSVC compiler with the /RTCs or /GZ
261 * flags. Disable the 'Stack frame run time error checking' for this function
262 * so we don't hit weird exceptions in debug builds. */
263 #if defined(_MSC_VER)
264 #pragma runtime_checks("s", off)
267 ffi_call_int (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
,
268 void **avalue
, void *closure
)
271 struct call_frame
*frame
;
273 ffi_type
**arg_types
;
274 int flags
, cabi
, i
, n
, dir
, narg_reg
;
275 const struct abi_params
*pabi
;
279 pabi
= &abi_params
[cabi
];
289 case X86_RET_LDOUBLE
:
290 case X86_RET_STRUCTPOP
:
291 case X86_RET_STRUCTARG
:
292 /* The float cases need to pop the 387 stack.
293 The struct cases need to pass a valid pointer to the callee. */
294 rsize
= cif
->rtype
->size
;
297 /* We can pretend that the callee returns nothing. */
298 flags
= X86_RET_VOID
;
303 bytes
= STACK_ALIGN (cif
->bytes
);
304 stack
= alloca(bytes
+ sizeof(*frame
) + rsize
);
305 argp
= (dir
< 0 ? stack
+ bytes
: stack
);
306 frame
= (struct call_frame
*)(stack
+ bytes
);
311 frame
->flags
= flags
;
312 frame
->rvalue
= rvalue
;
313 frame
->regs
[pabi
->static_chain
] = (unsigned)closure
;
318 case X86_RET_STRUCTARG
:
319 /* The pointer is passed as the first argument. */
322 frame
->regs
[pabi
->regs
[0]] = (unsigned)rvalue
;
327 case X86_RET_STRUCTPOP
:
328 *(void **)argp
= rvalue
;
329 argp
+= sizeof(void *);
333 arg_types
= cif
->arg_types
;
334 for (i
= 0, n
= cif
->nargs
; i
< n
; i
++)
336 ffi_type
*ty
= arg_types
[i
];
337 void *valp
= avalue
[i
];
341 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
)
343 ffi_arg val
= extend_basic_type (valp
, t
);
345 if (t
!= FFI_TYPE_FLOAT
&& narg_reg
< pabi
->nregs
)
346 frame
->regs
[pabi
->regs
[narg_reg
++]] = val
;
350 *(ffi_arg
*)argp
= val
;
354 *(ffi_arg
*)argp
= val
;
360 size_t za
= FFI_ALIGN (z
, FFI_SIZEOF_ARG
);
361 size_t align
= FFI_SIZEOF_ARG
;
363 /* Issue 434: For thiscall and fastcall, if the paramter passed
364 as 64-bit integer or struct, all following integer parameters
365 will be passed on stack. */
366 if ((cabi
== FFI_THISCALL
|| cabi
== FFI_FASTCALL
)
367 && (t
== FFI_TYPE_SINT64
368 || t
== FFI_TYPE_UINT64
369 || t
== FFI_TYPE_STRUCT
))
372 /* Alignment rules for arguments are quite complex. Vectors and
373 structures with 16 byte alignment get it. Note that long double
374 on Darwin does have 16 byte alignment, and does not get this
375 alignment if passed directly; a structure with a long double
376 inside, however, would get 16 byte alignment. Since libffi does
377 not support vectors, we need non concern ourselves with other
379 if (t
== FFI_TYPE_STRUCT
&& ty
->alignment
>= 16)
384 /* ??? These reverse argument ABIs are probably too old
385 to have cared about alignment. Someone should check. */
387 memcpy (argp
, valp
, z
);
391 argp
= (char *)FFI_ALIGN (argp
, align
);
392 memcpy (argp
, valp
, z
);
397 FFI_ASSERT (dir
> 0 || argp
== stack
);
399 ffi_call_i386 (frame
, stack
);
401 #if defined(_MSC_VER)
402 #pragma runtime_checks("s", restore)
406 ffi_call (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, void **avalue
)
408 ffi_call_int (cif
, fn
, rvalue
, avalue
, NULL
);
411 #ifdef FFI_GO_CLOSURES
413 ffi_call_go (ffi_cif
*cif
, void (*fn
)(void), void *rvalue
,
414 void **avalue
, void *closure
)
416 ffi_call_int (cif
, fn
, rvalue
, avalue
, closure
);
420 /** private members **/
422 void FFI_HIDDEN
ffi_closure_i386(void);
423 void FFI_HIDDEN
ffi_closure_STDCALL(void);
424 void FFI_HIDDEN
ffi_closure_REGISTER(void);
425 #if defined(FFI_EXEC_STATIC_TRAMP)
426 void FFI_HIDDEN
ffi_closure_i386_alt(void);
427 void FFI_HIDDEN
ffi_closure_STDCALL_alt(void);
428 void FFI_HIDDEN
ffi_closure_REGISTER_alt(void);
433 unsigned rettemp
[4]; /* 0 */
434 unsigned regs
[3]; /* 16-24 */
435 ffi_cif
*cif
; /* 28 */
436 void (*fun
)(ffi_cif
*,void*,void**,void*); /* 32 */
437 void *user_data
; /* 36 */
440 int FFI_HIDDEN FFI_DECLARE_FASTCALL
441 ffi_closure_inner (struct closure_frame
*frame
, char *stack
)
443 ffi_cif
*cif
= frame
->cif
;
444 int cabi
, i
, n
, flags
, dir
, narg_reg
;
445 const struct abi_params
*pabi
;
446 ffi_type
**arg_types
;
454 rvalue
= frame
->rettemp
;
455 pabi
= &abi_params
[cabi
];
457 argp
= (dir
< 0 ? stack
+ STACK_ALIGN (cif
->bytes
) : stack
);
461 case X86_RET_STRUCTARG
:
464 rvalue
= (void *)frame
->regs
[pabi
->regs
[0]];
466 frame
->rettemp
[0] = (unsigned)rvalue
;
470 case X86_RET_STRUCTPOP
:
471 rvalue
= *(void **)argp
;
472 argp
+= sizeof(void *);
473 frame
->rettemp
[0] = (unsigned)rvalue
;
478 avalue
= alloca(sizeof(void *) * n
);
480 arg_types
= cif
->arg_types
;
481 for (i
= 0; i
< n
; ++i
)
483 ffi_type
*ty
= arg_types
[i
];
488 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
)
490 if (t
!= FFI_TYPE_FLOAT
&& narg_reg
< pabi
->nregs
)
491 valp
= &frame
->regs
[pabi
->regs
[narg_reg
++]];
505 size_t za
= FFI_ALIGN (z
, FFI_SIZEOF_ARG
);
506 size_t align
= FFI_SIZEOF_ARG
;
508 /* See the comment in ffi_call_int. */
509 if (t
== FFI_TYPE_STRUCT
&& ty
->alignment
>= 16)
512 /* Issue 434: For thiscall and fastcall, if the paramter passed
513 as 64-bit integer or struct, all following integer parameters
514 will be passed on stack. */
515 if ((cabi
== FFI_THISCALL
|| cabi
== FFI_FASTCALL
)
516 && (t
== FFI_TYPE_SINT64
517 || t
== FFI_TYPE_UINT64
518 || t
== FFI_TYPE_STRUCT
))
523 /* ??? These reverse argument ABIs are probably too old
524 to have cared about alignment. Someone should check. */
530 argp
= (char *)FFI_ALIGN (argp
, align
);
539 frame
->fun (cif
, rvalue
, avalue
, frame
->user_data
);
544 return flags
| (cif
->bytes
<< X86_RET_POP_SHIFT
);
547 return flags
| ((cif
->bytes
- (narg_reg
* FFI_SIZEOF_ARG
))
548 << X86_RET_POP_SHIFT
);
555 ffi_prep_closure_loc (ffi_closure
* closure
,
557 void (*fun
)(ffi_cif
*,void*,void**,void*),
561 char *tramp
= closure
->tramp
;
563 int op
= 0xb8; /* movl imm, %eax */
569 dest
= ffi_closure_i386
;
575 dest
= ffi_closure_STDCALL
;
578 dest
= ffi_closure_REGISTER
;
579 op
= 0x68; /* pushl imm */
585 #if defined(FFI_EXEC_STATIC_TRAMP)
586 if (ffi_tramp_is_present(closure
))
588 /* Initialize the static trampoline's parameters. */
589 if (dest
== ffi_closure_i386
)
590 dest
= ffi_closure_i386_alt
;
591 else if (dest
== ffi_closure_STDCALL
)
592 dest
= ffi_closure_STDCALL_alt
;
594 dest
= ffi_closure_REGISTER_alt
;
595 ffi_tramp_set_parms (closure
->ftramp
, dest
, closure
);
600 /* Initialize the dynamic trampoline. */
602 *(UINT32
*) tramp
= 0xfb1e0ff3;
604 /* movl or pushl immediate. */
606 *(void **)(tramp
+ 5) = codeloc
;
610 *(unsigned *)(tramp
+ 10) = (unsigned)dest
- ((unsigned)codeloc
+ 14);
615 closure
->user_data
= user_data
;
620 #ifdef FFI_GO_CLOSURES
622 void FFI_HIDDEN
ffi_go_closure_EAX(void);
623 void FFI_HIDDEN
ffi_go_closure_ECX(void);
624 void FFI_HIDDEN
ffi_go_closure_STDCALL(void);
627 ffi_prep_go_closure (ffi_go_closure
* closure
, ffi_cif
* cif
,
628 void (*fun
)(ffi_cif
*,void*,void**,void*))
636 dest
= ffi_go_closure_ECX
;
640 dest
= ffi_go_closure_EAX
;
644 dest
= ffi_go_closure_STDCALL
;
651 closure
->tramp
= dest
;
658 #endif /* FFI_GO_CLOSURES */
660 /* ------- Native raw API support -------------------------------- */
664 void FFI_HIDDEN
ffi_closure_raw_SYSV(void);
665 void FFI_HIDDEN
ffi_closure_raw_THISCALL(void);
668 ffi_prep_raw_closure_loc (ffi_raw_closure
*closure
,
670 void (*fun
)(ffi_cif
*,void*,ffi_raw
*,void*),
674 char *tramp
= closure
->tramp
;
678 /* We currently don't support certain kinds of arguments for raw
679 closures. This should be implemented by a separate assembly
680 language routine, since it would require argument processing,
681 something we don't do now for performance. */
682 for (i
= cif
->nargs
-1; i
>= 0; i
--)
683 switch (cif
->arg_types
[i
]->type
)
685 case FFI_TYPE_STRUCT
:
686 case FFI_TYPE_LONGDOUBLE
:
687 return FFI_BAD_TYPEDEF
;
693 dest
= ffi_closure_raw_THISCALL
;
696 dest
= ffi_closure_raw_SYSV
;
702 /* movl imm, %eax. */
704 *(void **)(tramp
+ 1) = codeloc
;
708 *(unsigned *)(tramp
+ 6) = (unsigned)dest
- ((unsigned)codeloc
+ 10);
712 closure
->user_data
= user_data
;
718 ffi_raw_call(ffi_cif
*cif
, void (*fn
)(void), void *rvalue
, ffi_raw
*avalue
)
721 struct call_frame
*frame
;
723 ffi_type
**arg_types
;
724 int flags
, cabi
, i
, n
, narg_reg
;
725 const struct abi_params
*pabi
;
729 pabi
= &abi_params
[cabi
];
738 case X86_RET_LDOUBLE
:
739 case X86_RET_STRUCTPOP
:
740 case X86_RET_STRUCTARG
:
741 /* The float cases need to pop the 387 stack.
742 The struct cases need to pass a valid pointer to the callee. */
743 rsize
= cif
->rtype
->size
;
746 /* We can pretend that the callee returns nothing. */
747 flags
= X86_RET_VOID
;
752 bytes
= STACK_ALIGN (cif
->bytes
);
754 (void *)((uintptr_t)alloca(bytes
+ sizeof(*frame
) + rsize
+ 15) & ~16);
755 frame
= (struct call_frame
*)(stack
+ bytes
);
760 frame
->flags
= flags
;
761 frame
->rvalue
= rvalue
;
766 case X86_RET_STRUCTARG
:
767 /* The pointer is passed as the first argument. */
770 frame
->regs
[pabi
->regs
[0]] = (unsigned)rvalue
;
775 case X86_RET_STRUCTPOP
:
776 *(void **)argp
= rvalue
;
777 argp
+= sizeof(void *);
778 bytes
-= sizeof(void *);
782 arg_types
= cif
->arg_types
;
783 for (i
= 0, n
= cif
->nargs
; narg_reg
< pabi
->nregs
&& i
< n
; i
++)
785 ffi_type
*ty
= arg_types
[i
];
789 if (z
<= FFI_SIZEOF_ARG
&& t
!= FFI_TYPE_STRUCT
&& t
!= FFI_TYPE_FLOAT
)
791 ffi_arg val
= extend_basic_type (avalue
, t
);
792 frame
->regs
[pabi
->regs
[narg_reg
++]] = val
;
797 memcpy (argp
, avalue
, z
);
798 z
= FFI_ALIGN (z
, FFI_SIZEOF_ARG
);
805 memcpy (argp
, avalue
, bytes
);
807 ffi_call_i386 (frame
, stack
);
809 #endif /* !FFI_NO_RAW_API */
811 #if defined(FFI_EXEC_STATIC_TRAMP)
813 ffi_tramp_arch (size_t *tramp_size
, size_t *map_size
)
815 extern void *trampoline_code_table
;
817 *map_size
= X86_TRAMP_MAP_SIZE
;
818 *tramp_size
= X86_TRAMP_SIZE
;
819 return &trampoline_code_table
;
823 #endif /* __i386__ */