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__ */