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) 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 void ffi_prep_args(char *stack, extended_cif *ecif); 47 void 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 size_t p_stack_args[2]; 55 void *p_stack_data[2]; 56 char *argp2 = stack; 57 int stack_args_count = 0; 58 int cabi = ecif->cif->abi; 59 #endif 60 61 argp = stack; 62 63 if ((ecif->cif->flags == FFI_TYPE_STRUCT 64 || ecif->cif->flags == FFI_TYPE_MS_STRUCT) 65 #ifdef X86_WIN64 66 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2 67 && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8) 68 #endif 69 ) 70 { 71 *(void **) argp = ecif->rvalue; 72 #ifndef X86_WIN64 73 /* For fastcall/thiscall this is first register-passed 74 argument. */ 75 if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL) 76 { 77 p_stack_args[stack_args_count] = sizeof (void*); 78 p_stack_data[stack_args_count] = argp; 79 ++stack_args_count; 80 } 81 #endif 82 argp += sizeof(void*); 83 } 84 85 p_argv = ecif->avalue; 86 87 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; 88 i != 0; 89 i--, p_arg++) 90 { 91 size_t z; 92 93 /* Align if necessary */ 94 if ((sizeof(void*) - 1) & (size_t) argp) 95 argp = (char *) ALIGN(argp, sizeof(void*)); 96 97 z = (*p_arg)->size; 98 #ifdef X86_WIN64 99 if (z > sizeof(ffi_arg) 100 || ((*p_arg)->type == FFI_TYPE_STRUCT 101 && (z != 1 && z != 2 && z != 4 && z != 8)) 102 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE 103 || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE) 104 #endif 105 ) 106 { 107 z = sizeof(ffi_arg); 108 *(void **)argp = *p_argv; 109 } 110 else if ((*p_arg)->type == FFI_TYPE_FLOAT) 111 { 112 memcpy(argp, *p_argv, z); 113 } 114 else 115 #endif 116 if (z < sizeof(ffi_arg)) 117 { 118 z = sizeof(ffi_arg); 119 switch ((*p_arg)->type) 120 { 121 case FFI_TYPE_SINT8: 122 *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv); 123 break; 124 125 case FFI_TYPE_UINT8: 126 *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv); 127 break; 128 129 case FFI_TYPE_SINT16: 130 *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv); 131 break; 132 133 case FFI_TYPE_UINT16: 134 *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv); 135 break; 136 137 case FFI_TYPE_SINT32: 138 *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv); 139 break; 140 141 case FFI_TYPE_UINT32: 142 *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv); 143 break; 144 145 case FFI_TYPE_STRUCT: 146 *(ffi_arg *) argp = *(ffi_arg *)(* p_argv); 147 break; 148 149 default: 150 FFI_ASSERT(0); 151 } 152 } 153 else 154 { 155 memcpy(argp, *p_argv, z); 156 } 157 158 #ifndef X86_WIN64 159 /* For thiscall/fastcall convention register-passed arguments 160 are the first two none-floating-point arguments with a size 161 smaller or equal to sizeof (void*). */ 162 if ((cabi == FFI_THISCALL && stack_args_count < 1) 163 || (cabi == FFI_FASTCALL && stack_args_count < 2)) 164 { 165 if (z <= 4 166 && ((*p_arg)->type != FFI_TYPE_FLOAT 167 && (*p_arg)->type != FFI_TYPE_STRUCT)) 168 { 169 p_stack_args[stack_args_count] = z; 170 p_stack_data[stack_args_count] = argp; 171 ++stack_args_count; 172 } 173 } 174 #endif 175 p_argv++; 176 #ifdef X86_WIN64 177 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1); 178 #else 179 argp += z; 180 #endif 181 } 182 183 #ifndef X86_WIN64 184 /* We need to move the register-passed arguments for thiscall/fastcall 185 on top of stack, so that those can be moved to registers ecx/edx by 186 call-handler. */ 187 if (stack_args_count > 0) 188 { 189 size_t zz = (p_stack_args[0] + 3) & ~3; 190 char *h; 191 192 /* Move first argument to top-stack position. */ 193 if (p_stack_data[0] != argp2) 194 { 195 h = alloca (zz + 1); 196 memcpy (h, p_stack_data[0], zz); 197 memmove (argp2 + zz, argp2, 198 (size_t) ((char *) p_stack_data[0] - (char*)argp2)); 199 memcpy (argp2, h, zz); 200 } 201 202 argp2 += zz; 203 --stack_args_count; 204 if (zz > 4) 205 stack_args_count = 0; 206 207 /* If we have a second argument, then move it on top 208 after the first one. */ 209 if (stack_args_count > 0 && p_stack_data[1] != argp2) 210 { 211 zz = p_stack_args[1]; 212 zz = (zz + 3) & ~3; 213 h = alloca (zz + 1); 214 h = alloca (zz + 1); 215 memcpy (h, p_stack_data[1], zz); 216 memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2)); 217 memcpy (argp2, h, zz); 218 } 219 } 220 #endif 221 return; 222 } 223 224 /* Perform machine dependent cif processing */ 225 ffi_status ffi_prep_cif_machdep(ffi_cif *cif) 226 { 227 unsigned int i; 228 ffi_type **ptr; 229 230 /* Set the return type flag */ 231 switch (cif->rtype->type) 232 { 233 case FFI_TYPE_VOID: 234 case FFI_TYPE_UINT8: 235 case FFI_TYPE_UINT16: 236 case FFI_TYPE_SINT8: 237 case FFI_TYPE_SINT16: 238 #ifdef X86_WIN64 239 case FFI_TYPE_UINT32: 240 case FFI_TYPE_SINT32: 241 #endif 242 case FFI_TYPE_SINT64: 243 case FFI_TYPE_FLOAT: 244 case FFI_TYPE_DOUBLE: 245 #ifndef X86_WIN64 246 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE 247 case FFI_TYPE_LONGDOUBLE: 248 #endif 249 #endif 250 cif->flags = (unsigned) cif->rtype->type; 251 break; 252 253 case FFI_TYPE_UINT64: 254 #ifdef X86_WIN64 255 case FFI_TYPE_POINTER: 256 #endif 257 cif->flags = FFI_TYPE_SINT64; 258 break; 259 260 case FFI_TYPE_STRUCT: 261 #ifndef X86 262 if (cif->rtype->size == 1) 263 { 264 cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ 265 } 266 else if (cif->rtype->size == 2) 267 { 268 cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */ 269 } 270 else if (cif->rtype->size == 4) 271 { 272 #ifdef X86_WIN64 273 cif->flags = FFI_TYPE_SMALL_STRUCT_4B; 274 #else 275 cif->flags = FFI_TYPE_INT; /* same as int type */ 276 #endif 277 } 278 else if (cif->rtype->size == 8) 279 { 280 cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ 281 } 282 else 283 #endif 284 { 285 #ifdef X86_WIN32 286 if (cif->abi == FFI_MS_CDECL) 287 cif->flags = FFI_TYPE_MS_STRUCT; 288 else 289 #endif 290 cif->flags = FFI_TYPE_STRUCT; 291 /* allocate space for return value pointer */ 292 cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); 293 } 294 break; 295 296 default: 297 #ifdef X86_WIN64 298 cif->flags = FFI_TYPE_SINT64; 299 break; 300 case FFI_TYPE_INT: 301 cif->flags = FFI_TYPE_SINT32; 302 #else 303 cif->flags = FFI_TYPE_INT; 304 #endif 305 break; 306 } 307 308 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) 309 { 310 if (((*ptr)->alignment - 1) & cif->bytes) 311 cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); 312 cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG); 313 } 314 315 #ifdef X86_WIN64 316 /* ensure space for storing four registers */ 317 cif->bytes += 4 * sizeof(ffi_arg); 318 #endif 319 320 #ifndef X86_WIN32 321 #ifndef X86_WIN64 322 if (cif->abi != FFI_STDCALL && cif->abi != FFI_THISCALL && cif->abi != FFI_FASTCALL) 323 #endif 324 cif->bytes = (cif->bytes + 15) & ~0xF; 325 #endif 326 327 return FFI_OK; 328 } 329 330 #ifdef X86_WIN64 331 extern int 332 ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *, 333 unsigned, unsigned, unsigned *, void (*fn)(void)); 334 #elif defined(X86_WIN32) 335 extern void 336 ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *, 337 unsigned, unsigned, unsigned, unsigned *, void (*fn)(void)); 338 #else 339 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, 340 unsigned, unsigned, unsigned *, void (*fn)(void)); 341 #endif 342 343 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 344 { 345 extended_cif ecif; 346 347 ecif.cif = cif; 348 ecif.avalue = avalue; 349 350 /* If the return value is a struct and we don't have a return */ 351 /* value address then we need to make one */ 352 353 #ifdef X86_WIN64 354 if (rvalue == NULL 355 && cif->flags == FFI_TYPE_STRUCT 356 && cif->rtype->size != 1 && cif->rtype->size != 2 357 && cif->rtype->size != 4 && cif->rtype->size != 8) 358 { 359 ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF); 360 } 361 #else 362 if (rvalue == NULL 363 && (cif->flags == FFI_TYPE_STRUCT 364 || cif->flags == FFI_TYPE_MS_STRUCT)) 365 { 366 ecif.rvalue = alloca(cif->rtype->size); 367 } 368 #endif 369 else 370 ecif.rvalue = rvalue; 371 372 373 switch (cif->abi) 374 { 375 #ifdef X86_WIN64 376 case FFI_WIN64: 377 ffi_call_win64(ffi_prep_args, &ecif, cif->bytes, 378 cif->flags, ecif.rvalue, fn); 379 break; 380 #elif defined(X86_WIN32) 381 case FFI_SYSV: 382 case FFI_MS_CDECL: 383 case FFI_STDCALL: 384 ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, 385 ecif.rvalue, fn); 386 break; 387 case FFI_THISCALL: 388 case FFI_FASTCALL: 389 { 390 unsigned int abi = cif->abi; 391 unsigned int i, passed_regs = 0; 392 393 if (cif->flags == FFI_TYPE_STRUCT) 394 ++passed_regs; 395 396 for (i=0; i < cif->nargs && passed_regs < 2;i++) 397 { 398 size_t sz; 399 400 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT 401 || cif->arg_types[i]->type == FFI_TYPE_STRUCT) 402 continue; 403 sz = (cif->arg_types[i]->size + 3) & ~3; 404 if (sz == 0 || sz > 4) 405 continue; 406 ++passed_regs; 407 } 408 if (passed_regs < 2 && abi == FFI_FASTCALL) 409 abi = FFI_THISCALL; 410 if (passed_regs < 1 && abi == FFI_THISCALL) 411 abi = FFI_STDCALL; 412 ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags, 413 ecif.rvalue, fn); 414 } 415 break; 416 #else 417 case FFI_SYSV: 418 ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, 419 fn); 420 break; 421 #endif 422 default: 423 FFI_ASSERT(0); 424 break; 425 } 426 } 427 428 429 /** private members **/ 430 431 /* The following __attribute__((regparm(1))) decorations will have no effect 432 on MSVC or SUNPRO_C -- standard conventions apply. */ 433 static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, 434 void** args, ffi_cif* cif); 435 void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) 436 __attribute__ ((regparm(1))); 437 unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) 438 __attribute__ ((regparm(1))); 439 void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) 440 __attribute__ ((regparm(1))); 441 #ifdef X86_WIN32 442 void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *) 443 __attribute__ ((regparm(1))); 444 #endif 445 #ifndef X86_WIN64 446 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) 447 __attribute__ ((regparm(1))); 448 void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *) 449 __attribute__ ((regparm(1))); 450 void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *) 451 __attribute__ ((regparm(1))); 452 #else 453 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *); 454 #endif 455 456 /* This function is jumped to by the trampoline */ 457 458 #ifdef X86_WIN64 459 void * FFI_HIDDEN 460 ffi_closure_win64_inner (ffi_closure *closure, void *args) { 461 ffi_cif *cif; 462 void **arg_area; 463 void *result; 464 void *resp = &result; 465 466 cif = closure->cif; 467 arg_area = (void**) alloca (cif->nargs * sizeof (void*)); 468 469 /* this call will initialize ARG_AREA, such that each 470 * element in that array points to the corresponding 471 * value on the stack; and if the function returns 472 * a structure, it will change RESP to point to the 473 * structure return address. */ 474 475 ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif); 476 477 (closure->fun) (cif, resp, arg_area, closure->user_data); 478 479 /* The result is returned in rax. This does the right thing for 480 result types except for floats; we have to 'mov xmm0, rax' in the 481 caller to correct this. 482 TODO: structure sizes of 3 5 6 7 are returned by reference, too!!! 483 */ 484 return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp; 485 } 486 487 #else 488 unsigned int FFI_HIDDEN __attribute__ ((regparm(1))) 489 ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args) 490 { 491 /* our various things... */ 492 ffi_cif *cif; 493 void **arg_area; 494 495 cif = closure->cif; 496 arg_area = (void**) alloca (cif->nargs * sizeof (void*)); 497 498 /* this call will initialize ARG_AREA, such that each 499 * element in that array points to the corresponding 500 * value on the stack; and if the function returns 501 * a structure, it will change RESP to point to the 502 * structure return address. */ 503 504 ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); 505 506 (closure->fun) (cif, *respp, arg_area, closure->user_data); 507 508 return cif->flags; 509 } 510 #endif /* !X86_WIN64 */ 511 512 static void 513 ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, 514 ffi_cif *cif) 515 { 516 register unsigned int i; 517 register void **p_argv; 518 register char *argp; 519 register ffi_type **p_arg; 520 521 argp = stack; 522 523 #ifdef X86_WIN64 524 if (cif->rtype->size > sizeof(ffi_arg) 525 || (cif->flags == FFI_TYPE_STRUCT 526 && (cif->rtype->size != 1 && cif->rtype->size != 2 527 && cif->rtype->size != 4 && cif->rtype->size != 8))) { 528 *rvalue = *(void **) argp; 529 argp += sizeof(void *); 530 } 531 #else 532 if ( cif->flags == FFI_TYPE_STRUCT 533 || cif->flags == FFI_TYPE_MS_STRUCT ) { 534 *rvalue = *(void **) argp; 535 argp += sizeof(void *); 536 } 537 #endif 538 539 p_argv = avalue; 540 541 for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) 542 { 543 size_t z; 544 545 /* Align if necessary */ 546 if ((sizeof(void*) - 1) & (size_t) argp) { 547 argp = (char *) ALIGN(argp, sizeof(void*)); 548 } 549 550 #ifdef X86_WIN64 551 if ((*p_arg)->size > sizeof(ffi_arg) 552 || ((*p_arg)->type == FFI_TYPE_STRUCT 553 && ((*p_arg)->size != 1 && (*p_arg)->size != 2 554 && (*p_arg)->size != 4 && (*p_arg)->size != 8))) 555 { 556 z = sizeof(void *); 557 *p_argv = *(void **)argp; 558 } 559 else 560 #endif 561 { 562 z = (*p_arg)->size; 563 564 /* because we're little endian, this is what it turns into. */ 565 566 *p_argv = (void*) argp; 567 } 568 569 p_argv++; 570 #ifdef X86_WIN64 571 argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1); 572 #else 573 argp += z; 574 #endif 575 } 576 577 return; 578 } 579 580 #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \ 581 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 582 void* __fun = (void*)(FUN); \ 583 void* __ctx = (void*)(CTX); \ 584 *(unsigned char*) &__tramp[0] = 0x41; \ 585 *(unsigned char*) &__tramp[1] = 0xbb; \ 586 *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \ 587 *(unsigned char*) &__tramp[6] = 0x48; \ 588 *(unsigned char*) &__tramp[7] = 0xb8; \ 589 *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \ 590 *(unsigned char *) &__tramp[16] = 0x49; \ 591 *(unsigned char *) &__tramp[17] = 0xba; \ 592 *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \ 593 *(unsigned char *) &__tramp[26] = 0x41; \ 594 *(unsigned char *) &__tramp[27] = 0xff; \ 595 *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \ 596 } 597 598 /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ 599 600 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ 601 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 602 unsigned int __fun = (unsigned int)(FUN); \ 603 unsigned int __ctx = (unsigned int)(CTX); \ 604 unsigned int __dis = __fun - (__ctx + 10); \ 605 *(unsigned char*) &__tramp[0] = 0xb8; \ 606 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ 607 *(unsigned char *) &__tramp[5] = 0xe9; \ 608 *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ 609 } 610 611 #define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \ 612 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 613 unsigned int __fun = (unsigned int)(FUN); \ 614 unsigned int __ctx = (unsigned int)(CTX); \ 615 unsigned int __dis = __fun - (__ctx + 49); \ 616 unsigned short __size = (unsigned short)(SIZE); \ 617 *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \ 618 *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \ 619 *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \ 620 *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \ 621 *(unsigned char*) &__tramp[13] = 0xb8; \ 622 *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \ 623 *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \ 624 *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \ 625 *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \ 626 *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \ 627 *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \ 628 *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \ 629 *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \ 630 *(unsigned char*) &__tramp[39] = 0xb8; \ 631 *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \ 632 *(unsigned char *) &__tramp[44] = 0xe8; \ 633 *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \ 634 *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \ 635 *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \ 636 } 637 638 #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX) \ 639 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 640 unsigned int __fun = (unsigned int)(FUN); \ 641 unsigned int __ctx = (unsigned int)(CTX); \ 642 unsigned int __dis = __fun - (__ctx + 10); \ 643 *(unsigned char*) &__tramp[0] = 0xb8; \ 644 *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ 645 *(unsigned char *) &__tramp[5] = 0xe8; \ 646 *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ 647 } 648 649 /* the cif must already be prep'ed */ 650 651 ffi_status 652 ffi_prep_closure_loc (ffi_closure* closure, 653 ffi_cif* cif, 654 void (*fun)(ffi_cif*,void*,void**,void*), 655 void *user_data, 656 void *codeloc) 657 { 658 #ifdef X86_WIN64 659 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE) 660 #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0) 661 if (cif->abi == FFI_WIN64) 662 { 663 int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3); 664 FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0], 665 &ffi_closure_win64, 666 codeloc, mask); 667 /* make sure we can execute here */ 668 } 669 #else 670 if (cif->abi == FFI_SYSV) 671 { 672 FFI_INIT_TRAMPOLINE (&closure->tramp[0], 673 &ffi_closure_SYSV, 674 (void*)codeloc); 675 } 676 else if (cif->abi == FFI_FASTCALL) 677 { 678 FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], 679 &ffi_closure_FASTCALL, 680 (void*)codeloc); 681 } 682 else if (cif->abi == FFI_THISCALL) 683 { 684 FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], 685 &ffi_closure_THISCALL, 686 (void*)codeloc); 687 } 688 else if (cif->abi == FFI_STDCALL) 689 { 690 FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], 691 &ffi_closure_STDCALL, 692 (void*)codeloc); 693 } 694 #ifdef X86_WIN32 695 else if (cif->abi == FFI_MS_CDECL) 696 { 697 FFI_INIT_TRAMPOLINE (&closure->tramp[0], 698 &ffi_closure_SYSV, 699 (void*)codeloc); 700 } 701 #endif /* X86_WIN32 */ 702 #endif /* !X86_WIN64 */ 703 else 704 { 705 return FFI_BAD_ABI; 706 } 707 708 closure->cif = cif; 709 closure->user_data = user_data; 710 closure->fun = fun; 711 712 return FFI_OK; 713 } 714 715 /* ------- Native raw API support -------------------------------- */ 716 717 #if !FFI_NO_RAW_API 718 719 ffi_status 720 ffi_prep_raw_closure_loc (ffi_raw_closure* closure, 721 ffi_cif* cif, 722 void (*fun)(ffi_cif*,void*,ffi_raw*,void*), 723 void *user_data, 724 void *codeloc) 725 { 726 int i; 727 728 if (cif->abi != FFI_SYSV 729 #ifdef X86_WIN32 730 && cif->abi != FFI_THISCALL 731 #endif 732 ) 733 return FFI_BAD_ABI; 734 735 /* we currently don't support certain kinds of arguments for raw 736 closures. This should be implemented by a separate assembly 737 language routine, since it would require argument processing, 738 something we don't do now for performance. */ 739 740 for (i = cif->nargs-1; i >= 0; i--) 741 { 742 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); 743 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); 744 } 745 746 #ifdef X86_WIN32 747 if (cif->abi == FFI_SYSV) 748 { 749 #endif 750 FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, 751 codeloc); 752 #ifdef X86_WIN32 753 } 754 else if (cif->abi == FFI_THISCALL) 755 { 756 FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes); 757 } 758 #endif 759 closure->cif = cif; 760 closure->user_data = user_data; 761 closure->fun = fun; 762 763 return FFI_OK; 764 } 765 766 static void 767 ffi_prep_args_raw(char *stack, extended_cif *ecif) 768 { 769 memcpy (stack, ecif->avalue, ecif->cif->bytes); 770 } 771 772 /* we borrow this routine from libffi (it must be changed, though, to 773 * actually call the function passed in the first argument. as of 774 * libffi-1.20, this is not the case.) 775 */ 776 777 void 778 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) 779 { 780 extended_cif ecif; 781 void **avalue = (void **)fake_avalue; 782 783 ecif.cif = cif; 784 ecif.avalue = avalue; 785 786 /* If the return value is a struct and we don't have a return */ 787 /* value address then we need to make one */ 788 789 #ifdef X86_WIN64 790 if (rvalue == NULL 791 && cif->flags == FFI_TYPE_STRUCT 792 && cif->rtype->size != 1 && cif->rtype->size != 2 793 && cif->rtype->size != 4 && cif->rtype->size != 8) 794 { 795 ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF); 796 } 797 #else 798 if (rvalue == NULL 799 && (cif->flags == FFI_TYPE_STRUCT 800 || cif->flags == FFI_TYPE_MS_STRUCT)) 801 { 802 ecif.rvalue = alloca(cif->rtype->size); 803 } 804 #endif 805 else 806 ecif.rvalue = rvalue; 807 808 809 switch (cif->abi) 810 { 811 #ifdef X86_WIN64 812 case FFI_WIN64: 813 ffi_call_win64(ffi_prep_args_raw, &ecif, cif->bytes, 814 cif->flags, ecif.rvalue, fn); 815 break; 816 #elif defined(X86_WIN32) 817 case FFI_SYSV: 818 case FFI_MS_CDECL: 819 case FFI_STDCALL: 820 ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, 821 ecif.rvalue, fn); 822 break; 823 case FFI_THISCALL: 824 case FFI_FASTCALL: 825 { 826 unsigned int abi = cif->abi; 827 unsigned int i, passed_regs = 0; 828 829 if (cif->flags == FFI_TYPE_STRUCT) 830 ++passed_regs; 831 832 for (i=0; i < cif->nargs && passed_regs < 2;i++) 833 { 834 size_t sz; 835 836 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT 837 || cif->arg_types[i]->type == FFI_TYPE_STRUCT) 838 continue; 839 sz = (cif->arg_types[i]->size + 3) & ~3; 840 if (sz == 0 || sz > 4) 841 continue; 842 ++passed_regs; 843 } 844 if (passed_regs < 2 && abi == FFI_FASTCALL) 845 abi = FFI_THISCALL; 846 if (passed_regs < 1 && abi == FFI_THISCALL) 847 abi = FFI_STDCALL; 848 ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags, 849 ecif.rvalue, fn); 850 } 851 break; 852 #else 853 case FFI_SYSV: 854 ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue, 855 fn); 856 break; 857 #endif 858 default: 859 FFI_ASSERT(0); 860 break; 861 } 862 } 863 864 #endif 865 866 #endif /* !__x86_64__ || X86_WIN64 */ 867 868