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