Ensure that users don't include ffitarget.h directly
[libffi.git] / .pc / win64-struct-args / src / x86 / ffi.c
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.
7
8 x86 Foreign Function Interface
9
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:
17
18 The above copyright notice and this permission notice shall be included
19 in all copies or substantial portions of the Software.
20
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 ----------------------------------------------------------------------- */
30
31 #if !defined(__x86_64__) || defined(_WIN64)
32
33 #ifdef _WIN64
34 #include <windows.h>
35 #endif
36
37 #include <ffi.h>
38 #include <ffi_common.h>
39
40 #include <stdlib.h>
41
42 /* ffi_prep_args is called by the assembly routine once stack space
43 has been allocated for the function's arguments */
44
45 void ffi_prep_args(char *stack, extended_cif *ecif)
46 {
47 register unsigned int i;
48 register void **p_argv;
49 register char *argp;
50 register ffi_type **p_arg;
51 #ifdef X86_WIN32
52 size_t p_stack_args[2];
53 void *p_stack_data[2];
54 char *argp2 = stack;
55 int stack_args_count = 0;
56 int cabi = ecif->cif->abi;
57 #endif
58
59 argp = stack;
60
61 if (ecif->cif->flags == FFI_TYPE_STRUCT
62 #ifdef X86_WIN64
63 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
64 && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
65 #endif
66 )
67 {
68 *(void **) argp = ecif->rvalue;
69 #ifdef X86_WIN32
70 /* For fastcall/thiscall this is first register-passed
71 argument. */
72 if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
73 {
74 p_stack_args[stack_args_count] = sizeof (void*);
75 p_stack_data[stack_args_count] = argp;
76 ++stack_args_count;
77 }
78 #endif
79 argp += sizeof(void*);
80 }
81
82 p_argv = ecif->avalue;
83
84 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
85 i != 0;
86 i--, p_arg++)
87 {
88 size_t z;
89
90 /* Align if necessary */
91 if ((sizeof(void*) - 1) & (size_t) argp)
92 argp = (char *) ALIGN(argp, sizeof(void*));
93
94 z = (*p_arg)->size;
95 #ifdef X86_WIN64
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)
101 #endif
102 )
103 {
104 z = sizeof(ffi_arg);
105 *(void **)argp = *p_argv;
106 }
107 else if ((*p_arg)->type == FFI_TYPE_FLOAT)
108 {
109 memcpy(argp, *p_argv, z);
110 }
111 else
112 #endif
113 if (z < sizeof(ffi_arg))
114 {
115 z = sizeof(ffi_arg);
116 switch ((*p_arg)->type)
117 {
118 case FFI_TYPE_SINT8:
119 *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
120 break;
121
122 case FFI_TYPE_UINT8:
123 *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
124 break;
125
126 case FFI_TYPE_SINT16:
127 *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
128 break;
129
130 case FFI_TYPE_UINT16:
131 *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
132 break;
133
134 case FFI_TYPE_SINT32:
135 *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
136 break;
137
138 case FFI_TYPE_UINT32:
139 *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
140 break;
141
142 case FFI_TYPE_STRUCT:
143 *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
144 break;
145
146 default:
147 FFI_ASSERT(0);
148 }
149 }
150 else
151 {
152 memcpy(argp, *p_argv, z);
153 }
154
155 #ifdef X86_WIN32
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))
161 {
162 if (z <= 4
163 && ((*p_arg)->type != FFI_TYPE_FLOAT
164 && (*p_arg)->type != FFI_TYPE_STRUCT))
165 {
166 p_stack_args[stack_args_count] = z;
167 p_stack_data[stack_args_count] = argp;
168 ++stack_args_count;
169 }
170 }
171 #endif
172 p_argv++;
173 #ifdef X86_WIN64
174 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
175 #else
176 argp += z;
177 #endif
178 }
179
180 #ifdef X86_WIN32
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
183 call-handler. */
184 if (stack_args_count > 0)
185 {
186 size_t zz = (p_stack_args[0] + 3) & ~3;
187 char *h;
188
189 /* Move first argument to top-stack position. */
190 if (p_stack_data[0] != argp2)
191 {
192 h = alloca (zz + 1);
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);
197 }
198
199 argp2 += zz;
200 --stack_args_count;
201 if (zz > 4)
202 stack_args_count = 0;
203
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)
207 {
208 zz = p_stack_args[1];
209 zz = (zz + 3) & ~3;
210 h = alloca (zz + 1);
211 h = alloca (zz + 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);
215 }
216 }
217 #endif
218 return;
219 }
220
221 /* Perform machine dependent cif processing */
222 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
223 {
224 unsigned int i;
225 ffi_type **ptr;
226
227 /* Set the return type flag */
228 switch (cif->rtype->type)
229 {
230 case FFI_TYPE_VOID:
231 #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
232 case FFI_TYPE_UINT8:
233 case FFI_TYPE_UINT16:
234 case FFI_TYPE_SINT8:
235 case FFI_TYPE_SINT16:
236 #endif
237 #ifdef X86_WIN64
238 case FFI_TYPE_UINT32:
239 case FFI_TYPE_SINT32:
240 #endif
241 case FFI_TYPE_SINT64:
242 case FFI_TYPE_FLOAT:
243 case FFI_TYPE_DOUBLE:
244 #ifndef X86_WIN64
245 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
246 case FFI_TYPE_LONGDOUBLE:
247 #endif
248 #endif
249 cif->flags = (unsigned) cif->rtype->type;
250 break;
251
252 case FFI_TYPE_UINT64:
253 #ifdef X86_WIN64
254 case FFI_TYPE_POINTER:
255 #endif
256 cif->flags = FFI_TYPE_SINT64;
257 break;
258
259 case FFI_TYPE_STRUCT:
260 #ifndef X86
261 if (cif->rtype->size == 1)
262 {
263 cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
264 }
265 else if (cif->rtype->size == 2)
266 {
267 cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
268 }
269 else if (cif->rtype->size == 4)
270 {
271 #ifdef X86_WIN64
272 cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
273 #else
274 cif->flags = FFI_TYPE_INT; /* same as int type */
275 #endif
276 }
277 else if (cif->rtype->size == 8)
278 {
279 cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
280 }
281 else
282 #endif
283 {
284 cif->flags = FFI_TYPE_STRUCT;
285 /* allocate space for return value pointer */
286 cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
287 }
288 break;
289
290 default:
291 #ifdef X86_WIN64
292 cif->flags = FFI_TYPE_SINT64;
293 break;
294 case FFI_TYPE_INT:
295 cif->flags = FFI_TYPE_SINT32;
296 #else
297 cif->flags = FFI_TYPE_INT;
298 #endif
299 break;
300 }
301
302 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
303 {
304 if (((*ptr)->alignment - 1) & cif->bytes)
305 cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
306 cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
307 }
308
309 #ifdef X86_WIN64
310 /* ensure space for storing four registers */
311 cif->bytes += 4 * sizeof(ffi_arg);
312 #endif
313
314 #ifdef X86_DARWIN
315 cif->bytes = (cif->bytes + 15) & ~0xF;
316 #endif
317
318 return FFI_OK;
319 }
320
321 #ifdef X86_WIN64
322 extern int
323 ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
324 unsigned, unsigned, unsigned *, void (*fn)(void));
325 #elif defined(X86_WIN32)
326 extern void
327 ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
328 unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
329 #else
330 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
331 unsigned, unsigned, unsigned *, void (*fn)(void));
332 #endif
333
334 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
335 {
336 extended_cif ecif;
337
338 ecif.cif = cif;
339 ecif.avalue = avalue;
340
341 /* If the return value is a struct and we don't have a return */
342 /* value address then we need to make one */
343
344 #ifdef X86_WIN64
345 if (rvalue == NULL
346 && cif->flags == FFI_TYPE_STRUCT
347 && cif->rtype->size != 1 && cif->rtype->size != 2
348 && cif->rtype->size != 4 && cif->rtype->size != 8)
349 {
350 ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
351 }
352 #else
353 if (rvalue == NULL
354 && cif->flags == FFI_TYPE_STRUCT)
355 {
356 ecif.rvalue = alloca(cif->rtype->size);
357 }
358 #endif
359 else
360 ecif.rvalue = rvalue;
361
362
363 switch (cif->abi)
364 {
365 #ifdef X86_WIN64
366 case FFI_WIN64:
367 {
368 /* Make copies of all struct arguments
369 NOTE: not sure if responsibility should be here or in caller */
370 unsigned int i;
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
377 #endif
378 )
379 {
380 void *local = alloca(size);
381 memcpy(local, avalue[i], size);
382 avalue[i] = local;
383 }
384 }
385 ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
386 cif->flags, ecif.rvalue, fn);
387 }
388 break;
389 #elif defined(X86_WIN32)
390 case FFI_SYSV:
391 case FFI_STDCALL:
392 ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
393 ecif.rvalue, fn);
394 break;
395 case FFI_THISCALL:
396 case FFI_FASTCALL:
397 {
398 unsigned int abi = cif->abi;
399 unsigned int i, passed_regs = 0;
400
401 if (cif->flags == FFI_TYPE_STRUCT)
402 ++passed_regs;
403
404 for (i=0; i < cif->nargs && passed_regs < 2;i++)
405 {
406 size_t sz;
407
408 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
409 || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
410 continue;
411 sz = (cif->arg_types[i]->size + 3) & ~3;
412 if (sz == 0 || sz > 4)
413 continue;
414 ++passed_regs;
415 }
416 if (passed_regs < 2 && abi == FFI_FASTCALL)
417 abi = FFI_THISCALL;
418 if (passed_regs < 1 && abi == FFI_THISCALL)
419 abi = FFI_STDCALL;
420 ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
421 ecif.rvalue, fn);
422 }
423 break;
424 #else
425 case FFI_SYSV:
426 ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
427 fn);
428 break;
429 #endif
430 default:
431 FFI_ASSERT(0);
432 break;
433 }
434 }
435
436
437 /** private members **/
438
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)));
449 #ifdef X86_WIN32
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)));
454 #endif
455 #ifdef X86_WIN64
456 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
457 #endif
458
459 /* This function is jumped to by the trampoline */
460
461 #ifdef X86_WIN64
462 void * FFI_HIDDEN
463 ffi_closure_win64_inner (ffi_closure *closure, void *args) {
464 ffi_cif *cif;
465 void **arg_area;
466 void *result;
467 void *resp = &result;
468
469 cif = closure->cif;
470 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
471
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. */
477
478 ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
479
480 (closure->fun) (cif, resp, arg_area, closure->user_data);
481
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!!!
486 */
487 return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
488 }
489
490 #else
491 unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
492 ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
493 {
494 /* our various things... */
495 ffi_cif *cif;
496 void **arg_area;
497
498 cif = closure->cif;
499 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
500
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. */
506
507 ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
508
509 (closure->fun) (cif, *respp, arg_area, closure->user_data);
510
511 return cif->flags;
512 }
513 #endif /* !X86_WIN64 */
514
515 static void
516 ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
517 ffi_cif *cif)
518 {
519 register unsigned int i;
520 register void **p_argv;
521 register char *argp;
522 register ffi_type **p_arg;
523
524 argp = stack;
525
526 #ifdef X86_WIN64
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 *);
533 }
534 #else
535 if ( cif->flags == FFI_TYPE_STRUCT ) {
536 *rvalue = *(void **) argp;
537 argp += sizeof(void *);
538 }
539 #endif
540
541 p_argv = avalue;
542
543 for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
544 {
545 size_t z;
546
547 /* Align if necessary */
548 if ((sizeof(void*) - 1) & (size_t) argp) {
549 argp = (char *) ALIGN(argp, sizeof(void*));
550 }
551
552 #ifdef X86_WIN64
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)))
557 {
558 z = sizeof(void *);
559 *p_argv = *(void **)argp;
560 }
561 else
562 #endif
563 {
564 z = (*p_arg)->size;
565
566 /* because we're little endian, this is what it turns into. */
567
568 *p_argv = (void*) argp;
569 }
570
571 p_argv++;
572 #ifdef X86_WIN64
573 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
574 #else
575 argp += z;
576 #endif
577 }
578
579 return;
580 }
581
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 */ \
598 }
599
600 /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
601
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 */ \
611 }
612
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 + 22); \
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) */ \
638 }
639
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 */ \
652 }
653
654 /* the cif must already be prep'ed */
655
656 ffi_status
657 ffi_prep_closure_loc (ffi_closure* closure,
658 ffi_cif* cif,
659 void (*fun)(ffi_cif*,void*,void**,void*),
660 void *user_data,
661 void *codeloc)
662 {
663 #ifdef X86_WIN64
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)
667 {
668 int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
669 FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
670 &ffi_closure_win64,
671 codeloc, mask);
672 /* make sure we can execute here */
673 }
674 #else
675 if (cif->abi == FFI_SYSV)
676 {
677 FFI_INIT_TRAMPOLINE (&closure->tramp[0],
678 &ffi_closure_SYSV,
679 (void*)codeloc);
680 }
681 #ifdef X86_WIN32
682 else if (cif->abi == FFI_THISCALL)
683 {
684 FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
685 &ffi_closure_THISCALL,
686 (void*)codeloc,
687 cif->bytes);
688 }
689 else if (cif->abi == FFI_STDCALL)
690 {
691 FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
692 &ffi_closure_STDCALL,
693 (void*)codeloc, cif->bytes);
694 }
695 #endif /* X86_WIN32 */
696 #endif /* !X86_WIN64 */
697 else
698 {
699 return FFI_BAD_ABI;
700 }
701
702 closure->cif = cif;
703 closure->user_data = user_data;
704 closure->fun = fun;
705
706 return FFI_OK;
707 }
708
709 /* ------- Native raw API support -------------------------------- */
710
711 #if !FFI_NO_RAW_API
712
713 ffi_status
714 ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
715 ffi_cif* cif,
716 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
717 void *user_data,
718 void *codeloc)
719 {
720 int i;
721
722 if (cif->abi != FFI_SYSV) {
723 return FFI_BAD_ABI;
724 }
725
726 /* we currently don't support certain kinds of arguments for raw
727 closures. This should be implemented by a separate assembly
728 language routine, since it would require argument processing,
729 something we don't do now for performance. */
730
731 for (i = cif->nargs-1; i >= 0; i--)
732 {
733 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
734 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
735 }
736
737
738 FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
739 codeloc);
740
741 closure->cif = cif;
742 closure->user_data = user_data;
743 closure->fun = fun;
744
745 return FFI_OK;
746 }
747
748 static void
749 ffi_prep_args_raw(char *stack, extended_cif *ecif)
750 {
751 memcpy (stack, ecif->avalue, ecif->cif->bytes);
752 }
753
754 /* we borrow this routine from libffi (it must be changed, though, to
755 * actually call the function passed in the first argument. as of
756 * libffi-1.20, this is not the case.)
757 */
758
759 void
760 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
761 {
762 extended_cif ecif;
763 void **avalue = (void **)fake_avalue;
764
765 ecif.cif = cif;
766 ecif.avalue = avalue;
767
768 /* If the return value is a struct and we don't have a return */
769 /* value address then we need to make one */
770
771 if ((rvalue == NULL) &&
772 (cif->rtype->type == FFI_TYPE_STRUCT))
773 {
774 ecif.rvalue = alloca(cif->rtype->size);
775 }
776 else
777 ecif.rvalue = rvalue;
778
779
780 switch (cif->abi)
781 {
782 #ifdef X86_WIN32
783 case FFI_SYSV:
784 case FFI_STDCALL:
785 ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
786 ecif.rvalue, fn);
787 break;
788 case FFI_THISCALL:
789 case FFI_FASTCALL:
790 {
791 unsigned int abi = cif->abi;
792 unsigned int i, passed_regs = 0;
793
794 if (cif->flags == FFI_TYPE_STRUCT)
795 ++passed_regs;
796
797 for (i=0; i < cif->nargs && passed_regs < 2;i++)
798 {
799 size_t sz;
800
801 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
802 || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
803 continue;
804 sz = (cif->arg_types[i]->size + 3) & ~3;
805 if (sz == 0 || sz > 4)
806 continue;
807 ++passed_regs;
808 }
809 if (passed_regs < 2 && abi == FFI_FASTCALL)
810 cif->abi = abi = FFI_THISCALL;
811 if (passed_regs < 1 && abi == FFI_THISCALL)
812 cif->abi = abi = FFI_STDCALL;
813 ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
814 ecif.rvalue, fn);
815 }
816 break;
817 #else
818 case FFI_SYSV:
819 ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
820 ecif.rvalue, fn);
821 break;
822 #endif
823 default:
824 FFI_ASSERT(0);
825 break;
826 }
827 }
828
829 #endif
830
831 #endif /* !__x86_64__ || X86_WIN64 */
832