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