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