• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ffi_prep_cif_machdep(ffi_cif * cif)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
extend_basic_type(void * arg,int type)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
ffi_call_int(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)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
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)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
ffi_call_go(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)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
ffi_closure_inner(struct closure_frame * frame,char * stack)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
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)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
ffi_prep_go_closure(ffi_go_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *))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
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)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
ffi_raw_call(ffi_cif * cif,void (* fn)(void),void * rvalue,ffi_raw * avalue)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__ */
762