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 #ifndef __SANITIZE_ADDRESS__
259 # ifdef __clang__
260 # if __has_feature(address_sanitizer)
261 # define __SANITIZE_ADDRESS__
262 # endif
263 # endif
264 #endif
265 #ifdef __SANITIZE_ADDRESS__
266 __attribute__((noinline,no_sanitize_address))
267 #endif
268 static void
ffi_call_int(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)269 ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
270 void **avalue, void *closure)
271 {
272 size_t rsize, bytes;
273 struct call_frame *frame;
274 char *stack, *argp;
275 ffi_type **arg_types;
276 int flags, cabi, i, n, dir, narg_reg;
277 const struct abi_params *pabi;
278
279 flags = cif->flags;
280 cabi = cif->abi;
281 pabi = &abi_params[cabi];
282 dir = pabi->dir;
283
284 rsize = 0;
285 if (rvalue == NULL)
286 {
287 switch (flags)
288 {
289 case X86_RET_FLOAT:
290 case X86_RET_DOUBLE:
291 case X86_RET_LDOUBLE:
292 case X86_RET_STRUCTPOP:
293 case X86_RET_STRUCTARG:
294 /* The float cases need to pop the 387 stack.
295 The struct cases need to pass a valid pointer to the callee. */
296 rsize = cif->rtype->size;
297 break;
298 default:
299 /* We can pretend that the callee returns nothing. */
300 flags = X86_RET_VOID;
301 break;
302 }
303 }
304
305 bytes = STACK_ALIGN (cif->bytes);
306 stack = alloca(bytes + sizeof(*frame) + rsize);
307 argp = (dir < 0 ? stack + bytes : stack);
308 frame = (struct call_frame *)(stack + bytes);
309 if (rsize)
310 rvalue = frame + 1;
311
312 frame->fn = fn;
313 frame->flags = flags;
314 frame->rvalue = rvalue;
315 frame->regs[pabi->static_chain] = (unsigned)closure;
316
317 narg_reg = 0;
318 switch (flags)
319 {
320 case X86_RET_STRUCTARG:
321 /* The pointer is passed as the first argument. */
322 if (pabi->nregs > 0)
323 {
324 frame->regs[pabi->regs[0]] = (unsigned)rvalue;
325 narg_reg = 1;
326 break;
327 }
328 /* fallthru */
329 case X86_RET_STRUCTPOP:
330 *(void **)argp = rvalue;
331 argp += sizeof(void *);
332 break;
333 }
334
335 arg_types = cif->arg_types;
336 for (i = 0, n = cif->nargs; i < n; i++)
337 {
338 ffi_type *ty = arg_types[i];
339 void *valp = avalue[i];
340 size_t z = ty->size;
341 int t = ty->type;
342
343 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
344 {
345 ffi_arg val = extend_basic_type (valp, t);
346
347 if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
348 frame->regs[pabi->regs[narg_reg++]] = val;
349 else if (dir < 0)
350 {
351 argp -= 4;
352 *(ffi_arg *)argp = val;
353 }
354 else
355 {
356 *(ffi_arg *)argp = val;
357 argp += 4;
358 }
359 }
360 else
361 {
362 size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
363 size_t align = FFI_SIZEOF_ARG;
364
365 /* Issue 434: For thiscall and fastcall, if the paramter passed
366 as 64-bit integer or struct, all following integer paramters
367 will be passed on stack. */
368 if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
369 && (t == FFI_TYPE_SINT64
370 || t == FFI_TYPE_UINT64
371 || t == FFI_TYPE_STRUCT))
372 narg_reg = 2;
373
374 /* Alignment rules for arguments are quite complex. Vectors and
375 structures with 16 byte alignment get it. Note that long double
376 on Darwin does have 16 byte alignment, and does not get this
377 alignment if passed directly; a structure with a long double
378 inside, however, would get 16 byte alignment. Since libffi does
379 not support vectors, we need non concern ourselves with other
380 cases. */
381 if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
382 align = 16;
383
384 if (dir < 0)
385 {
386 /* ??? These reverse argument ABIs are probably too old
387 to have cared about alignment. Someone should check. */
388 argp -= za;
389 memcpy (argp, valp, z);
390 }
391 else
392 {
393 argp = (char *)FFI_ALIGN (argp, align);
394 memcpy (argp, valp, z);
395 argp += za;
396 }
397 }
398 }
399 FFI_ASSERT (dir > 0 || argp == stack);
400
401 ffi_call_i386 (frame, stack);
402 }
403
404 void
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)405 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
406 {
407 ffi_call_int (cif, fn, rvalue, avalue, NULL);
408 }
409
410 void
ffi_call_go(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)411 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
412 void **avalue, void *closure)
413 {
414 ffi_call_int (cif, fn, rvalue, avalue, closure);
415 }
416
417 /** private members **/
418
419 void FFI_HIDDEN ffi_closure_i386(void);
420 void FFI_HIDDEN ffi_closure_STDCALL(void);
421 void FFI_HIDDEN ffi_closure_REGISTER(void);
422
423 struct closure_frame
424 {
425 unsigned rettemp[4]; /* 0 */
426 unsigned regs[3]; /* 16-24 */
427 ffi_cif *cif; /* 28 */
428 void (*fun)(ffi_cif*,void*,void**,void*); /* 32 */
429 void *user_data; /* 36 */
430 };
431
432 int FFI_HIDDEN FFI_DECLARE_FASTCALL
ffi_closure_inner(struct closure_frame * frame,char * stack)433 ffi_closure_inner (struct closure_frame *frame, char *stack)
434 {
435 ffi_cif *cif = frame->cif;
436 int cabi, i, n, flags, dir, narg_reg;
437 const struct abi_params *pabi;
438 ffi_type **arg_types;
439 char *argp;
440 void *rvalue;
441 void **avalue;
442
443 cabi = cif->abi;
444 flags = cif->flags;
445 narg_reg = 0;
446 rvalue = frame->rettemp;
447 pabi = &abi_params[cabi];
448 dir = pabi->dir;
449 argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
450
451 switch (flags)
452 {
453 case X86_RET_STRUCTARG:
454 if (pabi->nregs > 0)
455 {
456 rvalue = (void *)frame->regs[pabi->regs[0]];
457 narg_reg = 1;
458 frame->rettemp[0] = (unsigned)rvalue;
459 break;
460 }
461 /* fallthru */
462 case X86_RET_STRUCTPOP:
463 rvalue = *(void **)argp;
464 argp += sizeof(void *);
465 frame->rettemp[0] = (unsigned)rvalue;
466 break;
467 }
468
469 n = cif->nargs;
470 avalue = alloca(sizeof(void *) * n);
471
472 arg_types = cif->arg_types;
473 for (i = 0; i < n; ++i)
474 {
475 ffi_type *ty = arg_types[i];
476 size_t z = ty->size;
477 int t = ty->type;
478 void *valp;
479
480 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)
481 {
482 if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)
483 valp = &frame->regs[pabi->regs[narg_reg++]];
484 else if (dir < 0)
485 {
486 argp -= 4;
487 valp = argp;
488 }
489 else
490 {
491 valp = argp;
492 argp += 4;
493 }
494 }
495 else
496 {
497 size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
498 size_t align = FFI_SIZEOF_ARG;
499
500 /* See the comment in ffi_call_int. */
501 if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
502 align = 16;
503
504 /* Issue 434: For thiscall and fastcall, if the paramter passed
505 as 64-bit integer or struct, all following integer paramters
506 will be passed on stack. */
507 if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
508 && (t == FFI_TYPE_SINT64
509 || t == FFI_TYPE_UINT64
510 || t == FFI_TYPE_STRUCT))
511 narg_reg = 2;
512
513 if (dir < 0)
514 {
515 /* ??? These reverse argument ABIs are probably too old
516 to have cared about alignment. Someone should check. */
517 argp -= za;
518 valp = argp;
519 }
520 else
521 {
522 argp = (char *)FFI_ALIGN (argp, align);
523 valp = argp;
524 argp += za;
525 }
526 }
527
528 avalue[i] = valp;
529 }
530
531 frame->fun (cif, rvalue, avalue, frame->user_data);
532
533 if (cabi == FFI_STDCALL)
534 return flags + (cif->bytes << X86_RET_POP_SHIFT);
535 else
536 return flags;
537 }
538
539 ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)540 ffi_prep_closure_loc (ffi_closure* closure,
541 ffi_cif* cif,
542 void (*fun)(ffi_cif*,void*,void**,void*),
543 void *user_data,
544 void *codeloc)
545 {
546 char *tramp = closure->tramp;
547 void (*dest)(void);
548 int op = 0xb8; /* movl imm, %eax */
549
550 switch (cif->abi)
551 {
552 case FFI_SYSV:
553 case FFI_THISCALL:
554 case FFI_FASTCALL:
555 case FFI_MS_CDECL:
556 dest = ffi_closure_i386;
557 break;
558 case FFI_STDCALL:
559 case FFI_PASCAL:
560 dest = ffi_closure_STDCALL;
561 break;
562 case FFI_REGISTER:
563 dest = ffi_closure_REGISTER;
564 op = 0x68; /* pushl imm */
565 break;
566 default:
567 return FFI_BAD_ABI;
568 }
569
570 /* movl or pushl immediate. */
571 tramp[0] = op;
572 *(void **)(tramp + 1) = codeloc;
573
574 /* jmp dest */
575 tramp[5] = 0xe9;
576 *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
577
578 closure->cif = cif;
579 closure->fun = fun;
580 closure->user_data = user_data;
581
582 return FFI_OK;
583 }
584
585 void FFI_HIDDEN ffi_go_closure_EAX(void);
586 void FFI_HIDDEN ffi_go_closure_ECX(void);
587 void FFI_HIDDEN ffi_go_closure_STDCALL(void);
588
589 ffi_status
ffi_prep_go_closure(ffi_go_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *))590 ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
591 void (*fun)(ffi_cif*,void*,void**,void*))
592 {
593 void (*dest)(void);
594
595 switch (cif->abi)
596 {
597 case FFI_SYSV:
598 case FFI_MS_CDECL:
599 dest = ffi_go_closure_ECX;
600 break;
601 case FFI_THISCALL:
602 case FFI_FASTCALL:
603 dest = ffi_go_closure_EAX;
604 break;
605 case FFI_STDCALL:
606 case FFI_PASCAL:
607 dest = ffi_go_closure_STDCALL;
608 break;
609 case FFI_REGISTER:
610 default:
611 return FFI_BAD_ABI;
612 }
613
614 closure->tramp = dest;
615 closure->cif = cif;
616 closure->fun = fun;
617
618 return FFI_OK;
619 }
620
621 /* ------- Native raw API support -------------------------------- */
622
623 #if !FFI_NO_RAW_API
624
625 void FFI_HIDDEN ffi_closure_raw_SYSV(void);
626 void FFI_HIDDEN ffi_closure_raw_THISCALL(void);
627
628 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)629 ffi_prep_raw_closure_loc (ffi_raw_closure *closure,
630 ffi_cif *cif,
631 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
632 void *user_data,
633 void *codeloc)
634 {
635 char *tramp = closure->tramp;
636 void (*dest)(void);
637 int i;
638
639 /* We currently don't support certain kinds of arguments for raw
640 closures. This should be implemented by a separate assembly
641 language routine, since it would require argument processing,
642 something we don't do now for performance. */
643 for (i = cif->nargs-1; i >= 0; i--)
644 switch (cif->arg_types[i]->type)
645 {
646 case FFI_TYPE_STRUCT:
647 case FFI_TYPE_LONGDOUBLE:
648 return FFI_BAD_TYPEDEF;
649 }
650
651 switch (cif->abi)
652 {
653 case FFI_THISCALL:
654 dest = ffi_closure_raw_THISCALL;
655 break;
656 case FFI_SYSV:
657 dest = ffi_closure_raw_SYSV;
658 break;
659 default:
660 return FFI_BAD_ABI;
661 }
662
663 /* movl imm, %eax. */
664 tramp[0] = 0xb8;
665 *(void **)(tramp + 1) = codeloc;
666
667 /* jmp dest */
668 tramp[5] = 0xe9;
669 *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);
670
671 closure->cif = cif;
672 closure->fun = fun;
673 closure->user_data = user_data;
674
675 return FFI_OK;
676 }
677
678 void
ffi_raw_call(ffi_cif * cif,void (* fn)(void),void * rvalue,ffi_raw * avalue)679 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
680 {
681 size_t rsize, bytes;
682 struct call_frame *frame;
683 char *stack, *argp;
684 ffi_type **arg_types;
685 int flags, cabi, i, n, narg_reg;
686 const struct abi_params *pabi;
687
688 flags = cif->flags;
689 cabi = cif->abi;
690 pabi = &abi_params[cabi];
691
692 rsize = 0;
693 if (rvalue == NULL)
694 {
695 switch (flags)
696 {
697 case X86_RET_FLOAT:
698 case X86_RET_DOUBLE:
699 case X86_RET_LDOUBLE:
700 case X86_RET_STRUCTPOP:
701 case X86_RET_STRUCTARG:
702 /* The float cases need to pop the 387 stack.
703 The struct cases need to pass a valid pointer to the callee. */
704 rsize = cif->rtype->size;
705 break;
706 default:
707 /* We can pretend that the callee returns nothing. */
708 flags = X86_RET_VOID;
709 break;
710 }
711 }
712
713 bytes = STACK_ALIGN (cif->bytes);
714 argp = stack =
715 (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
716 frame = (struct call_frame *)(stack + bytes);
717 if (rsize)
718 rvalue = frame + 1;
719
720 frame->fn = fn;
721 frame->flags = flags;
722 frame->rvalue = rvalue;
723
724 narg_reg = 0;
725 switch (flags)
726 {
727 case X86_RET_STRUCTARG:
728 /* The pointer is passed as the first argument. */
729 if (pabi->nregs > 0)
730 {
731 frame->regs[pabi->regs[0]] = (unsigned)rvalue;
732 narg_reg = 1;
733 break;
734 }
735 /* fallthru */
736 case X86_RET_STRUCTPOP:
737 *(void **)argp = rvalue;
738 argp += sizeof(void *);
739 bytes -= sizeof(void *);
740 break;
741 }
742
743 arg_types = cif->arg_types;
744 for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)
745 {
746 ffi_type *ty = arg_types[i];
747 size_t z = ty->size;
748 int t = ty->type;
749
750 if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)
751 {
752 ffi_arg val = extend_basic_type (avalue, t);
753 frame->regs[pabi->regs[narg_reg++]] = val;
754 z = FFI_SIZEOF_ARG;
755 }
756 else
757 {
758 memcpy (argp, avalue, z);
759 z = FFI_ALIGN (z, FFI_SIZEOF_ARG);
760 argp += z;
761 }
762 avalue += z;
763 bytes -= z;
764 }
765 if (i < n)
766 memcpy (argp, avalue, bytes);
767
768 ffi_call_i386 (frame, stack);
769 }
770 #endif /* !FFI_NO_RAW_API */
771 #endif /* __i386__ */
772