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) || defined(__CYGWIN__)
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
43 /* ffi_prep_args is called by the assembly routine once stack space
44 has been allocated for the function's arguments */
45
46 unsigned int ffi_prep_args(char *stack, extended_cif *ecif);
ffi_prep_args(char * stack,extended_cif * ecif)47 unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
48 {
49 register unsigned int i;
50 register void **p_argv;
51 register char *argp;
52 register ffi_type **p_arg;
53 #ifndef X86_WIN64
54 const int cabi = ecif->cif->abi;
55 const int dir = (cabi == FFI_PASCAL || cabi == FFI_REGISTER) ? -1 : +1;
56 unsigned int stack_args_count = 0;
57 void *p_stack_data[3];
58 char *argp2 = stack;
59 #else
60 #define dir 1
61 #endif
62
63 argp = stack;
64
65 if ((ecif->cif->flags == FFI_TYPE_STRUCT
66 || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
67 #ifdef X86_WIN64
68 && ((ecif->cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
69 #endif
70 )
71 {
72 #ifndef X86_WIN64
73 /* For fastcall/thiscall/register this is first register-passed
74 argument. */
75 if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL || cabi == FFI_REGISTER)
76 {
77 p_stack_data[stack_args_count] = argp;
78 ++stack_args_count;
79 }
80 #endif
81
82 *(void **) argp = ecif->rvalue;
83 argp += sizeof(void*);
84 }
85
86 p_arg = ecif->cif->arg_types;
87 p_argv = ecif->avalue;
88 if (dir < 0)
89 {
90 const int nargs = ecif->cif->nargs - 1;
91 if (nargs > 0)
92 {
93 p_arg += nargs;
94 p_argv += nargs;
95 }
96 }
97
98 for (i = ecif->cif->nargs;
99 i != 0;
100 i--, p_arg += dir, p_argv += dir)
101 {
102 /* Align if necessary */
103 if ((sizeof(void*) - 1) & (size_t) argp)
104 argp = (char *) ALIGN(argp, sizeof(void*));
105
106 size_t z = (*p_arg)->size;
107
108 #ifdef X86_WIN64
109 if (z > FFI_SIZEOF_ARG
110 || ((*p_arg)->type == FFI_TYPE_STRUCT
111 && (z & (1 | 2 | 4 | 8)) == 0)
112 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
113 || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
114 #endif
115 )
116 {
117 z = FFI_SIZEOF_ARG;
118 *(void **)argp = *p_argv;
119 }
120 else if ((*p_arg)->type == FFI_TYPE_FLOAT)
121 {
122 memcpy(argp, *p_argv, z);
123 }
124 else
125 #endif
126 if (z < FFI_SIZEOF_ARG)
127 {
128 z = FFI_SIZEOF_ARG;
129 switch ((*p_arg)->type)
130 {
131 case FFI_TYPE_SINT8:
132 *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
133 break;
134
135 case FFI_TYPE_UINT8:
136 *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
137 break;
138
139 case FFI_TYPE_SINT16:
140 *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
141 break;
142
143 case FFI_TYPE_UINT16:
144 *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
145 break;
146
147 case FFI_TYPE_SINT32:
148 *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
149 break;
150
151 case FFI_TYPE_UINT32:
152 *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
153 break;
154
155 case FFI_TYPE_STRUCT:
156 *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
157 break;
158
159 default:
160 FFI_ASSERT(0);
161 }
162 }
163 else
164 {
165 memcpy(argp, *p_argv, z);
166 }
167
168 #ifndef X86_WIN64
169 /* For thiscall/fastcall/register convention register-passed arguments
170 are the first two none-floating-point arguments with a size
171 smaller or equal to sizeof (void*). */
172 if ((z == FFI_SIZEOF_ARG)
173 && ((cabi == FFI_REGISTER)
174 || (cabi == FFI_THISCALL && stack_args_count < 1)
175 || (cabi == FFI_FASTCALL && stack_args_count < 2))
176 && ((*p_arg)->type != FFI_TYPE_FLOAT && (*p_arg)->type != FFI_TYPE_STRUCT)
177 )
178 {
179 if (dir < 0 && stack_args_count > 2)
180 {
181 /* Iterating arguments backwards, so first register-passed argument
182 will be passed last. Shift temporary values to make place. */
183 p_stack_data[0] = p_stack_data[1];
184 p_stack_data[1] = p_stack_data[2];
185 stack_args_count = 2;
186 }
187
188 p_stack_data[stack_args_count] = argp;
189 ++stack_args_count;
190 }
191 #endif
192
193 #ifdef X86_WIN64
194 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
195 #else
196 argp += z;
197 #endif
198 }
199
200 #ifndef X86_WIN64
201 /* We need to move the register-passed arguments for thiscall/fastcall/register
202 on top of stack, so that those can be moved to registers by call-handler. */
203 if (stack_args_count > 0)
204 {
205 if (dir < 0 && stack_args_count > 1)
206 {
207 /* Reverse order if iterating arguments backwards */
208 ffi_arg tmp = *(ffi_arg*) p_stack_data[0];
209 *(ffi_arg*) p_stack_data[0] = *(ffi_arg*) p_stack_data[stack_args_count - 1];
210 *(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
211 }
212
213 int i;
214 for (i = 0; i < stack_args_count; i++)
215 {
216 if (p_stack_data[i] != argp2)
217 {
218 ffi_arg tmp = *(ffi_arg*) p_stack_data[i];
219 memmove (argp2 + FFI_SIZEOF_ARG, argp2, (size_t) ((char*) p_stack_data[i] - (char*)argp2));
220 *(ffi_arg *) argp2 = tmp;
221 }
222
223 argp2 += FFI_SIZEOF_ARG;
224 }
225 }
226
227 return stack_args_count;
228 #endif
229 return 0;
230 }
231
232 /* Perform machine dependent cif processing */
ffi_prep_cif_machdep(ffi_cif * cif)233 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
234 {
235 unsigned int i;
236 ffi_type **ptr;
237
238 /* Set the return type flag */
239 switch (cif->rtype->type)
240 {
241 case FFI_TYPE_VOID:
242 case FFI_TYPE_UINT8:
243 case FFI_TYPE_UINT16:
244 case FFI_TYPE_SINT8:
245 case FFI_TYPE_SINT16:
246 #ifdef X86_WIN64
247 case FFI_TYPE_UINT32:
248 case FFI_TYPE_SINT32:
249 #endif
250 case FFI_TYPE_SINT64:
251 case FFI_TYPE_FLOAT:
252 case FFI_TYPE_DOUBLE:
253 #ifndef X86_WIN64
254 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
255 case FFI_TYPE_LONGDOUBLE:
256 #endif
257 #endif
258 cif->flags = (unsigned) cif->rtype->type;
259 break;
260
261 case FFI_TYPE_UINT64:
262 #ifdef X86_WIN64
263 case FFI_TYPE_POINTER:
264 #endif
265 cif->flags = FFI_TYPE_SINT64;
266 break;
267
268 case FFI_TYPE_STRUCT:
269 #ifndef X86
270 if (cif->rtype->size == 1)
271 {
272 cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
273 }
274 else if (cif->rtype->size == 2)
275 {
276 cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
277 }
278 else if (cif->rtype->size == 4)
279 {
280 #ifdef X86_WIN64
281 cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
282 #else
283 cif->flags = FFI_TYPE_INT; /* same as int type */
284 #endif
285 }
286 else if (cif->rtype->size == 8)
287 {
288 cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
289 }
290 else
291 #endif
292 {
293 #ifdef X86_WIN32
294 if (cif->abi == FFI_MS_CDECL)
295 cif->flags = FFI_TYPE_MS_STRUCT;
296 else
297 #endif
298 cif->flags = FFI_TYPE_STRUCT;
299 /* allocate space for return value pointer */
300 cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
301 }
302 break;
303
304 default:
305 #ifdef X86_WIN64
306 cif->flags = FFI_TYPE_SINT64;
307 break;
308 case FFI_TYPE_INT:
309 cif->flags = FFI_TYPE_SINT32;
310 #else
311 cif->flags = FFI_TYPE_INT;
312 #endif
313 break;
314 }
315
316 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
317 {
318 if (((*ptr)->alignment - 1) & cif->bytes)
319 cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
320 cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
321 }
322
323 #ifdef X86_WIN64
324 /* ensure space for storing four registers */
325 cif->bytes += 4 * FFI_SIZEOF_ARG;
326 #endif
327
328 #ifndef X86_WIN32
329 #ifndef X86_WIN64
330 if (cif->abi == FFI_SYSV || cif->abi == FFI_UNIX64)
331 #endif
332 cif->bytes = (cif->bytes + 15) & ~0xF;
333 #endif
334
335 return FFI_OK;
336 }
337
338 #ifdef X86_WIN64
339 extern int
340 ffi_call_win64(unsigned int (*)(char *, extended_cif *), extended_cif *,
341 unsigned, unsigned, unsigned *, void (*fn)(void));
342 #else
343 extern void
344 ffi_call_win32(unsigned int (*)(char *, extended_cif *), extended_cif *,
345 unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
346 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
347 unsigned, unsigned, unsigned *, void (*fn)(void));
348 #endif
349
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)350 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
351 {
352 extended_cif ecif;
353
354 ecif.cif = cif;
355 ecif.avalue = avalue;
356
357 /* If the return value is a struct and we don't have a return */
358 /* value address then we need to make one */
359
360 #ifdef X86_WIN64
361 if (rvalue == NULL
362 && cif->flags == FFI_TYPE_STRUCT
363 && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0))
364 {
365 ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
366 }
367 #else
368 if (rvalue == NULL
369 && (cif->flags == FFI_TYPE_STRUCT
370 || cif->flags == FFI_TYPE_MS_STRUCT))
371 {
372 ecif.rvalue = alloca(cif->rtype->size);
373 }
374 #endif
375 else
376 ecif.rvalue = rvalue;
377
378
379 switch (cif->abi)
380 {
381 #ifdef X86_WIN64
382 case FFI_WIN64:
383 ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
384 cif->flags, ecif.rvalue, fn);
385 break;
386 #else
387 #ifndef X86_WIN32
388 case FFI_SYSV:
389 ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
390 fn);
391 break;
392 #else
393 case FFI_SYSV:
394 case FFI_MS_CDECL:
395 #endif
396 case FFI_STDCALL:
397 case FFI_THISCALL:
398 case FFI_FASTCALL:
399 case FFI_PASCAL:
400 case FFI_REGISTER:
401 ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
402 ecif.rvalue, fn);
403 break;
404 #endif
405 default:
406 FFI_ASSERT(0);
407 break;
408 }
409 }
410
411
412 /** private members **/
413
414 /* The following __attribute__((regparm(1))) decorations will have no effect
415 on MSVC or SUNPRO_C -- standard conventions apply. */
416 static unsigned int ffi_prep_incoming_args (char *stack, void **ret,
417 void** args, ffi_cif* cif);
418 void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
419 __attribute__ ((regparm(1)));
420 unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
421 __attribute__ ((regparm(1)));
422 unsigned int FFI_HIDDEN ffi_closure_WIN32_inner (ffi_closure *, void **, void *)
423 __attribute__ ((regparm(1)));
424 void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
425 __attribute__ ((regparm(1)));
426 #ifdef X86_WIN32
427 void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
428 __attribute__ ((regparm(1)));
429 #endif
430 #ifndef X86_WIN64
431 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *);
432 void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *);
433 void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *);
434 void FFI_HIDDEN ffi_closure_REGISTER (ffi_closure *);
435 #else
436 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
437 #endif
438
439 /* This function is jumped to by the trampoline */
440
441 #ifdef X86_WIN64
442 void * FFI_HIDDEN
ffi_closure_win64_inner(ffi_closure * closure,void * args)443 ffi_closure_win64_inner (ffi_closure *closure, void *args) {
444 ffi_cif *cif;
445 void **arg_area;
446 void *result;
447 void *resp = &result;
448
449 cif = closure->cif;
450 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
451
452 /* this call will initialize ARG_AREA, such that each
453 * element in that array points to the corresponding
454 * value on the stack; and if the function returns
455 * a structure, it will change RESP to point to the
456 * structure return address. */
457
458 ffi_prep_incoming_args(args, &resp, arg_area, cif);
459
460 (closure->fun) (cif, resp, arg_area, closure->user_data);
461
462 /* The result is returned in rax. This does the right thing for
463 result types except for floats; we have to 'mov xmm0, rax' in the
464 caller to correct this.
465 TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
466 */
467 return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
468 }
469
470 #else
471 unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
ffi_closure_SYSV_inner(ffi_closure * closure,void ** respp,void * args)472 ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
473 {
474 /* our various things... */
475 ffi_cif *cif;
476 void **arg_area;
477
478 cif = closure->cif;
479 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
480
481 /* this call will initialize ARG_AREA, such that each
482 * element in that array points to the corresponding
483 * value on the stack; and if the function returns
484 * a structure, it will change RESP to point to the
485 * structure return address. */
486
487 ffi_prep_incoming_args(args, respp, arg_area, cif);
488
489 (closure->fun) (cif, *respp, arg_area, closure->user_data);
490
491 return cif->flags;
492 }
493
494 unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
ffi_closure_WIN32_inner(ffi_closure * closure,void ** respp,void * args)495 ffi_closure_WIN32_inner (ffi_closure *closure, void **respp, void *args)
496 {
497 /* our various things... */
498 ffi_cif *cif;
499 void **arg_area;
500 unsigned int ret;
501
502 cif = closure->cif;
503 arg_area = (void**) alloca (cif->nargs * sizeof (void*));
504
505 /* this call will initialize ARG_AREA, such that each
506 * element in that array points to the corresponding
507 * value on the stack; and if the function returns
508 * a structure, it will change RESP to point to the
509 * structure return address. */
510
511 ret = ffi_prep_incoming_args(args, respp, arg_area, cif);
512
513 (closure->fun) (cif, *respp, arg_area, closure->user_data);
514
515 return ret;
516 }
517 #endif /* !X86_WIN64 */
518
519 static unsigned int
ffi_prep_incoming_args(char * stack,void ** rvalue,void ** avalue,ffi_cif * cif)520 ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
521 ffi_cif *cif)
522 {
523 register unsigned int i;
524 register void **p_argv;
525 register char *argp;
526 register ffi_type **p_arg;
527 #ifndef X86_WIN64
528 const int cabi = cif->abi;
529 const int dir = (cabi == FFI_PASCAL || cabi == FFI_REGISTER) ? -1 : +1;
530 const unsigned int max_stack_count = (cabi == FFI_THISCALL) ? 1
531 : (cabi == FFI_FASTCALL) ? 2
532 : (cabi == FFI_REGISTER) ? 3
533 : 0;
534 unsigned int passed_regs = 0;
535 void *p_stack_data[3] = { stack - 1 };
536 #else
537 #define dir 1
538 #endif
539
540 argp = stack;
541 #ifndef X86_WIN64
542 argp += max_stack_count * FFI_SIZEOF_ARG;
543 #endif
544
545 if ((cif->flags == FFI_TYPE_STRUCT
546 || cif->flags == FFI_TYPE_MS_STRUCT)
547 #ifdef X86_WIN64
548 && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
549 #endif
550 )
551 {
552 #ifndef X86_WIN64
553 if (passed_regs < max_stack_count)
554 {
555 *rvalue = *(void**) (stack + (passed_regs*FFI_SIZEOF_ARG));
556 ++passed_regs;
557 }
558 else
559 #endif
560 {
561 *rvalue = *(void **) argp;
562 argp += sizeof(void *);
563 }
564 }
565
566 #ifndef X86_WIN64
567 /* Do register arguments first */
568 for (i = 0, p_arg = cif->arg_types;
569 i < cif->nargs && passed_regs < max_stack_count;
570 i++, p_arg++)
571 {
572 if ((*p_arg)->type == FFI_TYPE_FLOAT
573 || (*p_arg)->type == FFI_TYPE_STRUCT)
574 continue;
575
576 size_t sz = (*p_arg)->size;
577 if(sz == 0 || sz > FFI_SIZEOF_ARG)
578 continue;
579
580 p_stack_data[passed_regs] = avalue + i;
581 avalue[i] = stack + (passed_regs*FFI_SIZEOF_ARG);
582 ++passed_regs;
583 }
584 #endif
585
586 p_arg = cif->arg_types;
587 p_argv = avalue;
588 if (dir < 0)
589 {
590 const int nargs = cif->nargs - 1;
591 if (nargs > 0)
592 {
593 p_arg += nargs;
594 p_argv += nargs;
595 }
596 }
597
598 for (i = cif->nargs;
599 i != 0;
600 i--, p_arg += dir, p_argv += dir)
601 {
602 /* Align if necessary */
603 if ((sizeof(void*) - 1) & (size_t) argp)
604 argp = (char *) ALIGN(argp, sizeof(void*));
605
606 size_t z = (*p_arg)->size;
607
608 #ifdef X86_WIN64
609 if (z > FFI_SIZEOF_ARG
610 || ((*p_arg)->type == FFI_TYPE_STRUCT
611 && (z & (1 | 2 | 4 | 8)) == 0)
612 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
613 || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
614 #endif
615 )
616 {
617 z = FFI_SIZEOF_ARG;
618 *p_argv = *(void **)argp;
619 }
620 else
621 #else
622 if (passed_regs > 0
623 && z <= FFI_SIZEOF_ARG
624 && (p_argv == p_stack_data[0]
625 || p_argv == p_stack_data[1]
626 || p_argv == p_stack_data[2]))
627 {
628 /* Already assigned a register value */
629 continue;
630 }
631 else
632 #endif
633 {
634 /* because we're little endian, this is what it turns into. */
635 *p_argv = (void*) argp;
636 }
637
638 #ifdef X86_WIN64
639 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
640 #else
641 argp += z;
642 #endif
643 }
644
645 return (size_t)argp - (size_t)stack;
646 }
647
648 #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
649 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
650 void* __fun = (void*)(FUN); \
651 void* __ctx = (void*)(CTX); \
652 *(unsigned char*) &__tramp[0] = 0x41; \
653 *(unsigned char*) &__tramp[1] = 0xbb; \
654 *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
655 *(unsigned char*) &__tramp[6] = 0x48; \
656 *(unsigned char*) &__tramp[7] = 0xb8; \
657 *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
658 *(unsigned char *) &__tramp[16] = 0x49; \
659 *(unsigned char *) &__tramp[17] = 0xba; \
660 *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
661 *(unsigned char *) &__tramp[26] = 0x41; \
662 *(unsigned char *) &__tramp[27] = 0xff; \
663 *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
664 }
665
666 /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
667
668 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
669 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
670 unsigned int __fun = (unsigned int)(FUN); \
671 unsigned int __ctx = (unsigned int)(CTX); \
672 unsigned int __dis = __fun - (__ctx + 10); \
673 *(unsigned char*) &__tramp[0] = 0xb8; \
674 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
675 *(unsigned char*) &__tramp[5] = 0xe9; \
676 *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
677 }
678
679 #define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \
680 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
681 unsigned int __fun = (unsigned int)(FUN); \
682 unsigned int __ctx = (unsigned int)(CTX); \
683 unsigned int __dis = __fun - (__ctx + 49); \
684 unsigned short __size = (unsigned short)(SIZE); \
685 *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
686 *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
687 *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
688 *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
689 *(unsigned char*) &__tramp[13] = 0xb8; \
690 *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
691 *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
692 *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
693 *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
694 *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
695 *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
696 *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
697 *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
698 *(unsigned char*) &__tramp[39] = 0xb8; \
699 *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
700 *(unsigned char *) &__tramp[44] = 0xe8; \
701 *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
702 *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
703 *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
704 }
705
706 #define FFI_INIT_TRAMPOLINE_WIN32(TRAMP,FUN,CTX) \
707 { unsigned char *__tramp = (unsigned char*)(TRAMP); \
708 unsigned int __fun = (unsigned int)(FUN); \
709 unsigned int __ctx = (unsigned int)(CTX); \
710 unsigned int __dis = __fun - (__ctx + 10); \
711 *(unsigned char*) &__tramp[0] = 0x68; \
712 *(unsigned int*) &__tramp[1] = __ctx; /* push __ctx */ \
713 *(unsigned char*) &__tramp[5] = 0xe9; \
714 *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
715 }
716
717 /* the cif must already be prep'ed */
718
719 ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)720 ffi_prep_closure_loc (ffi_closure* closure,
721 ffi_cif* cif,
722 void (*fun)(ffi_cif*,void*,void**,void*),
723 void *user_data,
724 void *codeloc)
725 {
726 #ifdef X86_WIN64
727 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
728 #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
729 if (cif->abi == FFI_WIN64)
730 {
731 int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
732 FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
733 &ffi_closure_win64,
734 codeloc, mask);
735 /* make sure we can execute here */
736 }
737 #else
738 if (cif->abi == FFI_SYSV)
739 {
740 FFI_INIT_TRAMPOLINE (&closure->tramp[0],
741 &ffi_closure_SYSV,
742 (void*)codeloc);
743 }
744 else if (cif->abi == FFI_REGISTER)
745 {
746 FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
747 &ffi_closure_REGISTER,
748 (void*)codeloc);
749 }
750 else if (cif->abi == FFI_FASTCALL)
751 {
752 FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
753 &ffi_closure_FASTCALL,
754 (void*)codeloc);
755 }
756 else if (cif->abi == FFI_THISCALL)
757 {
758 FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
759 &ffi_closure_THISCALL,
760 (void*)codeloc);
761 }
762 else if (cif->abi == FFI_STDCALL || cif->abi == FFI_PASCAL)
763 {
764 FFI_INIT_TRAMPOLINE_WIN32 (&closure->tramp[0],
765 &ffi_closure_STDCALL,
766 (void*)codeloc);
767 }
768 #ifdef X86_WIN32
769 else if (cif->abi == FFI_MS_CDECL)
770 {
771 FFI_INIT_TRAMPOLINE (&closure->tramp[0],
772 &ffi_closure_SYSV,
773 (void*)codeloc);
774 }
775 #endif /* X86_WIN32 */
776 #endif /* !X86_WIN64 */
777 else
778 {
779 return FFI_BAD_ABI;
780 }
781
782 closure->cif = cif;
783 closure->user_data = user_data;
784 closure->fun = fun;
785
786 return FFI_OK;
787 }
788
789 /* ------- Native raw API support -------------------------------- */
790
791 #if !FFI_NO_RAW_API
792
793 ffi_status
ffi_prep_raw_closure_loc(ffi_raw_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,ffi_raw *,void *),void * user_data,void * codeloc)794 ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
795 ffi_cif* cif,
796 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
797 void *user_data,
798 void *codeloc)
799 {
800 int i;
801
802 if (cif->abi != FFI_SYSV
803 #ifdef X86_WIN32
804 && cif->abi != FFI_THISCALL
805 #endif
806 )
807 return FFI_BAD_ABI;
808
809 /* we currently don't support certain kinds of arguments for raw
810 closures. This should be implemented by a separate assembly
811 language routine, since it would require argument processing,
812 something we don't do now for performance. */
813
814 for (i = cif->nargs-1; i >= 0; i--)
815 {
816 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
817 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
818 }
819
820 #ifdef X86_WIN32
821 if (cif->abi == FFI_SYSV)
822 {
823 #endif
824 FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
825 codeloc);
826 #ifdef X86_WIN32
827 }
828 else if (cif->abi == FFI_THISCALL)
829 {
830 FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes);
831 }
832 #endif
833 closure->cif = cif;
834 closure->user_data = user_data;
835 closure->fun = fun;
836
837 return FFI_OK;
838 }
839
840 static unsigned int
ffi_prep_args_raw(char * stack,extended_cif * ecif)841 ffi_prep_args_raw(char *stack, extended_cif *ecif)
842 {
843 const ffi_cif *cif = ecif->cif;
844 unsigned int i, passed_regs = 0;
845
846 #ifndef X86_WIN64
847 const unsigned int abi = cif->abi;
848 const unsigned int max_regs = (abi == FFI_THISCALL) ? 1
849 : (abi == FFI_FASTCALL) ? 2
850 : (abi == FFI_REGISTER) ? 3
851 : 0;
852
853 if (cif->flags == FFI_TYPE_STRUCT)
854 ++passed_regs;
855
856 for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
857 {
858 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
859 || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
860 continue;
861
862 size_t sz = cif->arg_types[i]->size;
863 if (sz == 0 || sz > FFI_SIZEOF_ARG)
864 continue;
865
866 ++passed_regs;
867 }
868 #endif
869
870 memcpy (stack, ecif->avalue, cif->bytes);
871 return passed_regs;
872 }
873
874 /* we borrow this routine from libffi (it must be changed, though, to
875 * actually call the function passed in the first argument. as of
876 * libffi-1.20, this is not the case.)
877 */
878
879 void
ffi_raw_call(ffi_cif * cif,void (* fn)(void),void * rvalue,ffi_raw * fake_avalue)880 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
881 {
882 extended_cif ecif;
883 void **avalue = (void **)fake_avalue;
884
885 ecif.cif = cif;
886 ecif.avalue = avalue;
887
888 /* If the return value is a struct and we don't have a return */
889 /* value address then we need to make one */
890
891 if (rvalue == NULL
892 && (cif->flags == FFI_TYPE_STRUCT
893 || cif->flags == FFI_TYPE_MS_STRUCT))
894 {
895 ecif.rvalue = alloca(cif->rtype->size);
896 }
897 else
898 ecif.rvalue = rvalue;
899
900
901 switch (cif->abi)
902 {
903 #ifndef X86_WIN32
904 case FFI_SYSV:
905 ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
906 ecif.rvalue, fn);
907 break;
908 #else
909 case FFI_SYSV:
910 case FFI_MS_CDECL:
911 #endif
912 #ifndef X86_WIN64
913 case FFI_STDCALL:
914 case FFI_THISCALL:
915 case FFI_FASTCALL:
916 case FFI_PASCAL:
917 case FFI_REGISTER:
918 ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
919 ecif.rvalue, fn);
920 break;
921 #endif
922 default:
923 FFI_ASSERT(0);
924 break;
925 }
926 }
927
928 #endif
929
930 #endif /* !__x86_64__ || X86_WIN64 */
931
932