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