Update Copyright years for files modified in 2010.
[official-gcc.git] / libffi / src / x86 / ffi.c
blobfea9d6deaf1396209de451c4a7d976ef726cbfdc
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)
33 #ifdef _WIN64
34 #include <windows.h>
35 #endif
37 #include <ffi.h>
38 #include <ffi_common.h>
40 #include <stdlib.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;
49 register char *argp;
50 register ffi_type **p_arg;
52 argp = stack;
54 if (ecif->cif->flags == FFI_TYPE_STRUCT
55 #ifdef X86_WIN64
56 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
57 && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
58 #endif
61 *(void **) argp = ecif->rvalue;
62 argp += sizeof(void*);
65 p_argv = ecif->avalue;
67 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
68 i != 0;
69 i--, p_arg++)
71 size_t z;
73 /* Align if necessary */
74 if ((sizeof(void*) - 1) & (size_t) argp)
75 argp = (char *) ALIGN(argp, sizeof(void*));
77 z = (*p_arg)->size;
78 #ifdef X86_WIN64
79 if (z > sizeof(ffi_arg)
80 || ((*p_arg)->type == FFI_TYPE_STRUCT
81 && (z != 1 && z != 2 && z != 4 && z != 8))
82 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
83 || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
84 #endif
87 z = sizeof(ffi_arg);
88 *(void **)argp = *p_argv;
90 else if ((*p_arg)->type == FFI_TYPE_FLOAT)
92 memcpy(argp, *p_argv, z);
94 else
95 #endif
96 if (z < sizeof(ffi_arg))
98 z = sizeof(ffi_arg);
99 switch ((*p_arg)->type)
101 case FFI_TYPE_SINT8:
102 *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
103 break;
105 case FFI_TYPE_UINT8:
106 *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
107 break;
109 case FFI_TYPE_SINT16:
110 *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
111 break;
113 case FFI_TYPE_UINT16:
114 *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
115 break;
117 case FFI_TYPE_SINT32:
118 *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
119 break;
121 case FFI_TYPE_UINT32:
122 *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
123 break;
125 case FFI_TYPE_STRUCT:
126 *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
127 break;
129 default:
130 FFI_ASSERT(0);
133 else
135 memcpy(argp, *p_argv, z);
137 p_argv++;
138 #ifdef X86_WIN64
139 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
140 #else
141 argp += z;
142 #endif
145 return;
148 /* Perform machine dependent cif processing */
149 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
151 unsigned int i;
152 ffi_type **ptr;
154 /* Set the return type flag */
155 switch (cif->rtype->type)
157 case FFI_TYPE_VOID:
158 #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
159 case FFI_TYPE_UINT8:
160 case FFI_TYPE_UINT16:
161 case FFI_TYPE_SINT8:
162 case FFI_TYPE_SINT16:
163 #endif
164 #ifdef X86_WIN64
165 case FFI_TYPE_UINT32:
166 case FFI_TYPE_SINT32:
167 #endif
168 case FFI_TYPE_SINT64:
169 case FFI_TYPE_FLOAT:
170 case FFI_TYPE_DOUBLE:
171 #ifndef X86_WIN64
172 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
173 case FFI_TYPE_LONGDOUBLE:
174 #endif
175 #endif
176 cif->flags = (unsigned) cif->rtype->type;
177 break;
179 case FFI_TYPE_UINT64:
180 #ifdef X86_WIN64
181 case FFI_TYPE_POINTER:
182 #endif
183 cif->flags = FFI_TYPE_SINT64;
184 break;
186 case FFI_TYPE_STRUCT:
187 #ifndef X86
188 if (cif->rtype->size == 1)
190 cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
192 else if (cif->rtype->size == 2)
194 cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
196 else if (cif->rtype->size == 4)
198 #ifdef X86_WIN64
199 cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
200 #else
201 cif->flags = FFI_TYPE_INT; /* same as int type */
202 #endif
204 else if (cif->rtype->size == 8)
206 cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
208 else
209 #endif
211 cif->flags = FFI_TYPE_STRUCT;
212 /* allocate space for return value pointer */
213 cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
215 break;
217 default:
218 #ifdef X86_WIN64
219 cif->flags = FFI_TYPE_SINT64;
220 break;
221 case FFI_TYPE_INT:
222 cif->flags = FFI_TYPE_SINT32;
223 #else
224 cif->flags = FFI_TYPE_INT;
225 #endif
226 break;
229 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
231 if (((*ptr)->alignment - 1) & cif->bytes)
232 cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
233 cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
236 #ifdef X86_WIN64
237 /* ensure space for storing four registers */
238 cif->bytes += 4 * sizeof(ffi_arg);
239 #endif
241 #ifdef X86_DARWIN
242 cif->bytes = (cif->bytes + 15) & ~0xF;
243 #endif
245 return FFI_OK;
248 #ifdef X86_WIN64
249 extern int
250 ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
251 unsigned, unsigned, unsigned *, void (*fn)(void));
252 #elif defined(X86_WIN32)
253 extern void
254 ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
255 unsigned, unsigned, unsigned *, void (*fn)(void));
256 #else
257 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
258 unsigned, unsigned, unsigned *, void (*fn)(void));
259 #endif
261 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
263 extended_cif ecif;
265 ecif.cif = cif;
266 ecif.avalue = avalue;
268 /* If the return value is a struct and we don't have a return */
269 /* value address then we need to make one */
271 #ifdef X86_WIN64
272 if (rvalue == NULL
273 && cif->flags == FFI_TYPE_STRUCT
274 && cif->rtype->size != 1 && cif->rtype->size != 2
275 && cif->rtype->size != 4 && cif->rtype->size != 8)
277 ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
279 #else
280 if (rvalue == NULL
281 && cif->flags == FFI_TYPE_STRUCT)
283 ecif.rvalue = alloca(cif->rtype->size);
285 #endif
286 else
287 ecif.rvalue = rvalue;
290 switch (cif->abi)
292 #ifdef X86_WIN64
293 case FFI_WIN64:
295 /* Make copies of all struct arguments
296 NOTE: not sure if responsibility should be here or in caller */
297 unsigned int i;
298 for (i=0; i < cif->nargs;i++) {
299 size_t size = cif->arg_types[i]->size;
300 if ((cif->arg_types[i]->type == FFI_TYPE_STRUCT
301 && (size != 1 && size != 2 && size != 4 && size != 8))
302 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
303 || cif->arg_types[i]->type == FFI_TYPE_LONGDOUBLE
304 #endif
307 void *local = alloca(size);
308 memcpy(local, avalue[i], size);
309 avalue[i] = local;
312 ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
313 cif->flags, ecif.rvalue, fn);
315 break;
316 #elif defined(X86_WIN32)
317 case FFI_SYSV:
318 case FFI_STDCALL:
319 ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
320 ecif.rvalue, fn);
321 break;
322 #else
323 case FFI_SYSV:
324 ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
325 fn);
326 break;
327 #endif
328 default:
329 FFI_ASSERT(0);
330 break;
335 /** private members **/
337 /* The following __attribute__((regparm(1))) decorations will have no effect
338 on MSVC - standard cdecl convention applies. */
339 static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
340 void** args, ffi_cif* cif);
341 void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
342 __attribute__ ((regparm(1)));
343 unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
344 __attribute__ ((regparm(1)));
345 void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
346 __attribute__ ((regparm(1)));
347 #ifdef X86_WIN32
348 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
349 __attribute__ ((regparm(1)));
350 #endif
351 #ifdef X86_WIN64
352 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
353 #endif
355 /* This function is jumped to by the trampoline */
357 #ifdef X86_WIN64
358 void * FFI_HIDDEN
359 ffi_closure_win64_inner (ffi_closure *closure, void *args) {
360 ffi_cif *cif;
361 void **arg_area;
362 void *result;
363 void *resp = &result;
365 cif = closure->cif;
366 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
368 /* this call will initialize ARG_AREA, such that each
369 * element in that array points to the corresponding
370 * value on the stack; and if the function returns
371 * a structure, it will change RESP to point to the
372 * structure return address. */
374 ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
376 (closure->fun) (cif, resp, arg_area, closure->user_data);
378 /* The result is returned in rax. This does the right thing for
379 result types except for floats; we have to 'mov xmm0, rax' in the
380 caller to correct this.
381 TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
383 return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
386 #else
387 unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
388 ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
390 /* our various things... */
391 ffi_cif *cif;
392 void **arg_area;
394 cif = closure->cif;
395 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
397 /* this call will initialize ARG_AREA, such that each
398 * element in that array points to the corresponding
399 * value on the stack; and if the function returns
400 * a structure, it will change RESP to point to the
401 * structure return address. */
403 ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
405 (closure->fun) (cif, *respp, arg_area, closure->user_data);
407 return cif->flags;
409 #endif /* !X86_WIN64 */
411 static void
412 ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
413 ffi_cif *cif)
415 register unsigned int i;
416 register void **p_argv;
417 register char *argp;
418 register ffi_type **p_arg;
420 argp = stack;
422 #ifdef X86_WIN64
423 if (cif->rtype->size > sizeof(ffi_arg)
424 || (cif->flags == FFI_TYPE_STRUCT
425 && (cif->rtype->size != 1 && cif->rtype->size != 2
426 && cif->rtype->size != 4 && cif->rtype->size != 8))) {
427 *rvalue = *(void **) argp;
428 argp += sizeof(void *);
430 #else
431 if ( cif->flags == FFI_TYPE_STRUCT ) {
432 *rvalue = *(void **) argp;
433 argp += sizeof(void *);
435 #endif
437 p_argv = avalue;
439 for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
441 size_t z;
443 /* Align if necessary */
444 if ((sizeof(void*) - 1) & (size_t) argp) {
445 argp = (char *) ALIGN(argp, sizeof(void*));
448 #ifdef X86_WIN64
449 if ((*p_arg)->size > sizeof(ffi_arg)
450 || ((*p_arg)->type == FFI_TYPE_STRUCT
451 && ((*p_arg)->size != 1 && (*p_arg)->size != 2
452 && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
454 z = sizeof(void *);
455 *p_argv = *(void **)argp;
457 else
458 #endif
460 z = (*p_arg)->size;
462 /* because we're little endian, this is what it turns into. */
464 *p_argv = (void*) argp;
467 p_argv++;
468 #ifdef X86_WIN64
469 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
470 #else
471 argp += z;
472 #endif
475 return;
478 #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
479 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
480 void* __fun = (void*)(FUN); \
481 void* __ctx = (void*)(CTX); \
482 *(unsigned char*) &__tramp[0] = 0x41; \
483 *(unsigned char*) &__tramp[1] = 0xbb; \
484 *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
485 *(unsigned char*) &__tramp[6] = 0x48; \
486 *(unsigned char*) &__tramp[7] = 0xb8; \
487 *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
488 *(unsigned char *) &__tramp[16] = 0x49; \
489 *(unsigned char *) &__tramp[17] = 0xba; \
490 *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
491 *(unsigned char *) &__tramp[26] = 0x41; \
492 *(unsigned char *) &__tramp[27] = 0xff; \
493 *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
496 /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
498 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
499 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
500 unsigned int __fun = (unsigned int)(FUN); \
501 unsigned int __ctx = (unsigned int)(CTX); \
502 unsigned int __dis = __fun - (__ctx + 10); \
503 *(unsigned char*) &__tramp[0] = 0xb8; \
504 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
505 *(unsigned char *) &__tramp[5] = 0xe9; \
506 *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
509 #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
510 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
511 unsigned int __fun = (unsigned int)(FUN); \
512 unsigned int __ctx = (unsigned int)(CTX); \
513 unsigned int __dis = __fun - (__ctx + 10); \
514 unsigned short __size = (unsigned short)(SIZE); \
515 *(unsigned char*) &__tramp[0] = 0xb8; \
516 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
517 *(unsigned char *) &__tramp[5] = 0xe8; \
518 *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
519 *(unsigned char *) &__tramp[10] = 0xc2; \
520 *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
523 /* the cif must already be prep'ed */
525 ffi_status
526 ffi_prep_closure_loc (ffi_closure* closure,
527 ffi_cif* cif,
528 void (*fun)(ffi_cif*,void*,void**,void*),
529 void *user_data,
530 void *codeloc)
532 #ifdef X86_WIN64
533 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
534 #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
535 if (cif->abi == FFI_WIN64)
537 int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
538 FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
539 &ffi_closure_win64,
540 codeloc, mask);
541 /* make sure we can execute here */
543 #else
544 if (cif->abi == FFI_SYSV)
546 FFI_INIT_TRAMPOLINE (&closure->tramp[0],
547 &ffi_closure_SYSV,
548 (void*)codeloc);
550 #ifdef X86_WIN32
551 else if (cif->abi == FFI_STDCALL)
553 FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
554 &ffi_closure_STDCALL,
555 (void*)codeloc, cif->bytes);
557 #endif /* X86_WIN32 */
558 #endif /* !X86_WIN64 */
559 else
561 return FFI_BAD_ABI;
564 closure->cif = cif;
565 closure->user_data = user_data;
566 closure->fun = fun;
568 return FFI_OK;
571 /* ------- Native raw API support -------------------------------- */
573 #if !FFI_NO_RAW_API
575 ffi_status
576 ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
577 ffi_cif* cif,
578 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
579 void *user_data,
580 void *codeloc)
582 int i;
584 if (cif->abi != FFI_SYSV) {
585 return FFI_BAD_ABI;
588 /* we currently don't support certain kinds of arguments for raw
589 closures. This should be implemented by a separate assembly
590 language routine, since it would require argument processing,
591 something we don't do now for performance. */
593 for (i = cif->nargs-1; i >= 0; i--)
595 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
596 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
600 FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
601 codeloc);
603 closure->cif = cif;
604 closure->user_data = user_data;
605 closure->fun = fun;
607 return FFI_OK;
610 static void
611 ffi_prep_args_raw(char *stack, extended_cif *ecif)
613 memcpy (stack, ecif->avalue, ecif->cif->bytes);
616 /* we borrow this routine from libffi (it must be changed, though, to
617 * actually call the function passed in the first argument. as of
618 * libffi-1.20, this is not the case.)
621 void
622 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
624 extended_cif ecif;
625 void **avalue = (void **)fake_avalue;
627 ecif.cif = cif;
628 ecif.avalue = avalue;
630 /* If the return value is a struct and we don't have a return */
631 /* value address then we need to make one */
633 if ((rvalue == NULL) &&
634 (cif->rtype->type == FFI_TYPE_STRUCT))
636 ecif.rvalue = alloca(cif->rtype->size);
638 else
639 ecif.rvalue = rvalue;
642 switch (cif->abi)
644 #ifdef X86_WIN32
645 case FFI_SYSV:
646 case FFI_STDCALL:
647 ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
648 ecif.rvalue, fn);
649 break;
650 #else
651 case FFI_SYSV:
652 ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
653 ecif.rvalue, fn);
654 break;
655 #endif
656 default:
657 FFI_ASSERT(0);
658 break;
662 #endif
664 #endif /* !__x86_64__ || X86_WIN64 */