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