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;
260 ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
261 void **avalue, void *closure)
264 struct call_frame *frame;
266 ffi_type **arg_types;
267 int flags, cabi, i, n, dir, narg_reg;
268 const struct abi_params *pabi;
272 pabi = &abi_params[cabi];
282 case X86_RET_LDOUBLE:
283 case X86_RET_STRUCTPOP:
284 case X86_RET_STRUCTARG:
285 /* The float cases need to pop the 387 stack.
286 The struct cases need to pass a valid pointer to the callee. */
287 rsize = cif->rtype->size;
290 /* We can pretend that the callee returns nothing. */
291 flags = X86_RET_VOID;
296 bytes = STACK_ALIGN (cif->bytes);
297 stack = alloca(bytes + sizeof(*frame) + rsize);
298 argp = (dir < 0 ? stack + bytes : stack);
299 frame = (struct call_frame *)(stack + bytes);
304 frame->flags = flags;
305 frame->rvalue = rvalue;
306 frame->regs[pabi->static_chain] = (unsigned)closure;
311 case X86_RET_STRUCTARG:
312 /* The pointer is passed as the first argument. */
315 frame->regs[pabi->regs[0]] = (unsigned)rvalue;
320 case X86_RET_STRUCTPOP:
321 *(void **)argp = rvalue;
322 argp += sizeof(void *);
326 arg_types = cif->arg_types;
327 for (i = 0, n = cif->nargs; i < n; i++)
329 ffi_type *ty = arg_types[i];
330 void *valp = avalue[i];
334 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
336 ffi_arg val = extend_basic_type (valp, t);
338 if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
339 frame->regs[pabi->regs[narg_reg++]] = val;
343 *(ffi_arg *)argp = val;
347 *(ffi_arg *)argp = val;
353 size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
354 size_t align = FFI_SIZEOF_ARG;
356 /* Issue 434: For thiscall and fastcall, if the paramter passed
357 as 64-bit integer or struct, all following integer parameters
358 will be passed on stack. */
359 if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
360 && (t == FFI_TYPE_SINT64
361 || t == FFI_TYPE_UINT64
362 || t == FFI_TYPE_STRUCT))
365 /* Alignment rules for arguments are quite complex. Vectors and
366 structures with 16 byte alignment get it. Note that long double
367 on Darwin does have 16 byte alignment, and does not get this
368 alignment if passed directly; a structure with a long double
369 inside, however, would get 16 byte alignment. Since libffi does
370 not support vectors, we need non concern ourselves with other
372 if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
377 /* ??? These reverse argument ABIs are probably too old
378 to have cared about alignment. Someone should check. */
380 memcpy (argp, valp, z);
384 argp = (char *)FFI_ALIGN (argp, align);
385 memcpy (argp, valp, z);
390 FFI_ASSERT (dir > 0 || argp == stack);
392 ffi_call_i386 (frame, stack);
396 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
398 ffi_call_int (cif, fn, rvalue, avalue, NULL);
401 #ifdef FFI_GO_CLOSURES
403 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
404 void **avalue, void *closure)
406 ffi_call_int (cif, fn, rvalue, avalue, closure);
410 /** private members **/
412 void FFI_HIDDEN ffi_closure_i386(void);
413 void FFI_HIDDEN ffi_closure_STDCALL(void);
414 void FFI_HIDDEN ffi_closure_REGISTER(void);
415 #if defined(FFI_EXEC_STATIC_TRAMP)
416 void FFI_HIDDEN ffi_closure_i386_alt(void);
417 void FFI_HIDDEN ffi_closure_STDCALL_alt(void);
418 void FFI_HIDDEN ffi_closure_REGISTER_alt(void);
423 unsigned rettemp[4]; /* 0 */
424 unsigned regs[3]; /* 16-24 */
425 ffi_cif *cif; /* 28 */
426 void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */
427 void *user_data; /* 36 */
430 int FFI_HIDDEN FFI_DECLARE_FASTCALL
431 ffi_closure_inner (struct closure_frame *frame, char *stack)
433 ffi_cif *cif = frame->cif;
434 int cabi, i, n, flags, dir, narg_reg;
435 const struct abi_params *pabi;
436 ffi_type **arg_types;
444 rvalue = frame->rettemp;
445 pabi = &abi_params[cabi];
447 argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
451 case X86_RET_STRUCTARG:
454 rvalue = (void *)frame->regs[pabi->regs[0]];
456 frame->rettemp[0] = (unsigned)rvalue;
460 case X86_RET_STRUCTPOP:
461 rvalue = *(void **)argp;
462 argp += sizeof(void *);
463 frame->rettemp[0] = (unsigned)rvalue;
468 avalue = alloca(sizeof(void *) * n);
470 arg_types = cif->arg_types;
471 for (i = 0; i < n; ++i)
473 ffi_type *ty = arg_types[i];
478 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
480 if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
481 valp = &frame->regs[pabi->regs[narg_reg++]];
495 size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
496 size_t align = FFI_SIZEOF_ARG;
498 /* See the comment in ffi_call_int. */
499 if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
502 /* Issue 434: For thiscall and fastcall, if the paramter passed
503 as 64-bit integer or struct, all following integer parameters
504 will be passed on stack. */
505 if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
506 && (t == FFI_TYPE_SINT64
507 || t == FFI_TYPE_UINT64
508 || t == FFI_TYPE_STRUCT))
513 /* ??? These reverse argument ABIs are probably too old
514 to have cared about alignment. Someone should check. */
520 argp = (char *)FFI_ALIGN (argp, align);
529 frame->fun (cif, rvalue, avalue, frame->user_data);
531 if (cabi == FFI_STDCALL)
532 return flags + (cif->bytes << X86_RET_POP_SHIFT);
538 ffi_prep_closure_loc (ffi_closure* closure,
540 void (*fun)(ffi_cif*,void*,void**,void*),
544 char *tramp = closure->tramp;
546 int op = 0xb8; /* movl imm, %eax */
554 dest = ffi_closure_i386;
558 dest = ffi_closure_STDCALL;
561 dest = ffi_closure_REGISTER;
562 op = 0x68; /* pushl imm */
568 #if defined(FFI_EXEC_STATIC_TRAMP)
569 if (ffi_tramp_is_present(closure))
571 /* Initialize the static trampoline's parameters. */
572 if (dest == ffi_closure_i386)
573 dest = ffi_closure_i386_alt;
574 else if (dest == ffi_closure_STDCALL)
575 dest = ffi_closure_STDCALL_alt;
577 dest = ffi_closure_REGISTER_alt;
578 ffi_tramp_set_parms (closure->ftramp, dest, closure);
583 /* Initialize the dynamic trampoline. */
585 *(UINT32 *) tramp = 0xfb1e0ff3;
587 /* movl or pushl immediate. */
589 *(void **)(tramp + 5) = codeloc;
593 *(unsigned *)(tramp + 10) = (unsigned)dest - ((unsigned)codeloc + 14);
598 closure->user_data = user_data;
603 #ifdef FFI_GO_CLOSURES
605 void FFI_HIDDEN ffi_go_closure_EAX(void);
606 void FFI_HIDDEN ffi_go_closure_ECX(void);
607 void FFI_HIDDEN ffi_go_closure_STDCALL(void);
610 ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
611 void (*fun)(ffi_cif*,void*,void**,void*))
619 dest = ffi_go_closure_ECX;
623 dest = ffi_go_closure_EAX;
627 dest = ffi_go_closure_STDCALL;
634 closure->tramp = dest;
641 #endif /* FFI_GO_CLOSURES */
643 /* ------- Native raw API support -------------------------------- */
647 void FFI_HIDDEN ffi_closure_raw_SYSV(void);
648 void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
651 ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
653 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
657 char *tramp = closure->tramp;
661 /* We currently don't support certain kinds of arguments for raw
662 closures. This should be implemented by a separate assembly
663 language routine, since it would require argument processing,
664 something we don't do now for performance. */
665 for (i = cif->nargs-1; i >= 0; i--)
666 switch (cif->arg_types[i]->type)
668 case FFI_TYPE_STRUCT:
669 case FFI_TYPE_LONGDOUBLE:
670 return FFI_BAD_TYPEDEF;
676 dest = ffi_closure_raw_THISCALL;
679 dest = ffi_closure_raw_SYSV;
685 /* movl imm, %eax. */
687 *(void **)(tramp + 1) = codeloc;
691 *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
695 closure->user_data = user_data;
701 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
704 struct call_frame *frame;
706 ffi_type **arg_types;
707 int flags, cabi, i, n, narg_reg;
708 const struct abi_params *pabi;
712 pabi = &abi_params[cabi];
721 case X86_RET_LDOUBLE:
722 case X86_RET_STRUCTPOP:
723 case X86_RET_STRUCTARG:
724 /* The float cases need to pop the 387 stack.
725 The struct cases need to pass a valid pointer to the callee. */
726 rsize = cif->rtype->size;
729 /* We can pretend that the callee returns nothing. */
730 flags = X86_RET_VOID;
735 bytes = STACK_ALIGN (cif->bytes);
737 (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
738 frame = (struct call_frame *)(stack + bytes);
743 frame->flags = flags;
744 frame->rvalue = rvalue;
749 case X86_RET_STRUCTARG:
750 /* The pointer is passed as the first argument. */
753 frame->regs[pabi->regs[0]] = (unsigned)rvalue;
758 case X86_RET_STRUCTPOP:
759 *(void **)argp = rvalue;
760 argp += sizeof(void *);
761 bytes -= sizeof(void *);
765 arg_types = cif->arg_types;
766 for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
768 ffi_type *ty = arg_types[i];
772 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
774 ffi_arg val = extend_basic_type (avalue, t);
775 frame->regs[pabi->regs[narg_reg++]] = val;
780 memcpy (argp, avalue, z);
781 z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
788 memcpy (argp, avalue, bytes);
790 ffi_call_i386 (frame, stack);
792 #endif /* !FFI_NO_RAW_API */
794 #if defined(FFI_EXEC_STATIC_TRAMP)
796 ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
798 extern void *trampoline_code_table;
800 *map_size = X86_TRAMP_MAP_SIZE;
801 *tramp_size = X86_TRAMP_SIZE;
802 return &trampoline_code_table;
806 #endif /* __i386__ */