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