< prev index next >

modules/javafx.media/src/main/native/gstreamer/3rd_party/libffi/src/x86/ffi.c

Print this page

  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__ */
< prev index next >