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