1 /* ----------------------------------------------------------------------- 2 ffi.c - Copyright (c) 2011, 2013 Anthony Green 3 Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc. 4 5 SPARC Foreign Function Interface 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 ``Software''), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be included 16 in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 ----------------------------------------------------------------------- */ 27 28 #include <ffi.h> 29 #include <ffi_common.h> 30 31 #include <stdlib.h> 32 33 34 /* ffi_prep_args is called by the assembly routine once stack space 35 has been allocated for the function's arguments */ 36 37 void ffi_prep_args_v8(char *stack, extended_cif *ecif) 38 { 39 int i; 40 void **p_argv; 41 char *argp; 42 ffi_type **p_arg; 43 44 /* Skip 16 words for the window save area */ 45 argp = stack + 16*sizeof(int); 46 47 /* This should only really be done when we are returning a structure, 48 however, it's faster just to do it all the time... 49 50 if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */ 51 *(int *) argp = (long)ecif->rvalue; 52 53 /* And 1 word for the structure return value. */ 54 argp += sizeof(int); 55 56 #ifdef USING_PURIFY 57 /* Purify will probably complain in our assembly routine, unless we 58 zero out this memory. */ 59 60 ((int*)argp)[0] = 0; 61 ((int*)argp)[1] = 0; 62 ((int*)argp)[2] = 0; 63 ((int*)argp)[3] = 0; 64 ((int*)argp)[4] = 0; 65 ((int*)argp)[5] = 0; 66 #endif 67 68 p_argv = ecif->avalue; 69 70 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++) 71 { 72 size_t z; 73 74 if ((*p_arg)->type == FFI_TYPE_STRUCT 75 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 76 || (*p_arg)->type == FFI_TYPE_LONGDOUBLE 77 #endif 78 ) 79 { 80 *(unsigned int *) argp = (unsigned long)(* p_argv); 81 z = sizeof(int); 82 } 83 else 84 { 85 z = (*p_arg)->size; 86 if (z < sizeof(int)) 87 { 88 z = sizeof(int); 89 switch ((*p_arg)->type) 90 { 91 case FFI_TYPE_SINT8: 92 *(signed int *) argp = *(SINT8 *)(* p_argv); 93 break; 94 95 case FFI_TYPE_UINT8: 96 *(unsigned int *) argp = *(UINT8 *)(* p_argv); 97 break; 98 99 case FFI_TYPE_SINT16: 100 *(signed int *) argp = *(SINT16 *)(* p_argv); 101 break; 102 103 case FFI_TYPE_UINT16: 104 *(unsigned int *) argp = *(UINT16 *)(* p_argv); 105 break; 106 107 default: 108 FFI_ASSERT(0); 109 } 110 } 111 else 112 { 113 memcpy(argp, *p_argv, z); 114 } 115 } 116 p_argv++; 117 argp += z; 118 } 119 120 return; 121 } 122 123 int ffi_prep_args_v9(char *stack, extended_cif *ecif) 124 { 125 int i, ret = 0; 126 int tmp; 127 void **p_argv; 128 char *argp; 129 ffi_type **p_arg; 130 131 tmp = 0; 132 133 /* Skip 16 words for the window save area */ 134 argp = stack + 16*sizeof(long long); 135 136 #ifdef USING_PURIFY 137 /* Purify will probably complain in our assembly routine, unless we 138 zero out this memory. */ 139 140 ((long long*)argp)[0] = 0; 141 ((long long*)argp)[1] = 0; 142 ((long long*)argp)[2] = 0; 143 ((long long*)argp)[3] = 0; 144 ((long long*)argp)[4] = 0; 145 ((long long*)argp)[5] = 0; 146 #endif 147 148 p_argv = ecif->avalue; 149 150 if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && 151 ecif->cif->rtype->size > 32) 152 { 153 *(unsigned long long *) argp = (unsigned long)ecif->rvalue; 154 argp += sizeof(long long); 155 tmp = 1; 156 } 157 158 for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; 159 i++, p_arg++) 160 { 161 size_t z; 162 163 z = (*p_arg)->size; 164 switch ((*p_arg)->type) 165 { 166 case FFI_TYPE_STRUCT: 167 if (z > 16) 168 { 169 /* For structures larger than 16 bytes we pass reference. */ 170 *(unsigned long long *) argp = (unsigned long)* p_argv; 171 argp += sizeof(long long); 172 tmp++; 173 p_argv++; 174 continue; 175 } 176 /* FALLTHROUGH */ 177 case FFI_TYPE_FLOAT: 178 case FFI_TYPE_DOUBLE: 179 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 180 case FFI_TYPE_LONGDOUBLE: 181 #endif 182 ret = 1; /* We should promote into FP regs as well as integer. */ 183 break; 184 } 185 if (z < sizeof(long long)) 186 { 187 switch ((*p_arg)->type) 188 { 189 case FFI_TYPE_SINT8: 190 *(signed long long *) argp = *(SINT8 *)(* p_argv); 191 break; 192 193 case FFI_TYPE_UINT8: 194 *(unsigned long long *) argp = *(UINT8 *)(* p_argv); 195 break; 196 197 case FFI_TYPE_SINT16: 198 *(signed long long *) argp = *(SINT16 *)(* p_argv); 199 break; 200 201 case FFI_TYPE_UINT16: 202 *(unsigned long long *) argp = *(UINT16 *)(* p_argv); 203 break; 204 205 case FFI_TYPE_SINT32: 206 *(signed long long *) argp = *(SINT32 *)(* p_argv); 207 break; 208 209 case FFI_TYPE_UINT32: 210 *(unsigned long long *) argp = *(UINT32 *)(* p_argv); 211 break; 212 213 case FFI_TYPE_FLOAT: 214 *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */ 215 break; 216 217 case FFI_TYPE_STRUCT: 218 memcpy(argp, *p_argv, z); 219 break; 220 221 default: 222 FFI_ASSERT(0); 223 } 224 z = sizeof(long long); 225 tmp++; 226 } 227 else if (z == sizeof(long long)) 228 { 229 memcpy(argp, *p_argv, z); 230 z = sizeof(long long); 231 tmp++; 232 } 233 else 234 { 235 if ((tmp & 1) && (*p_arg)->alignment > 8) 236 { 237 tmp++; 238 argp += sizeof(long long); 239 } 240 memcpy(argp, *p_argv, z); 241 z = 2 * sizeof(long long); 242 tmp += 2; 243 } 244 p_argv++; 245 argp += z; 246 } 247 248 return ret; 249 } 250 251 /* Perform machine dependent cif processing */ 252 ffi_status ffi_prep_cif_machdep(ffi_cif *cif) 253 { 254 int wordsize; 255 256 if (cif->abi != FFI_V9) 257 { 258 wordsize = 4; 259 260 /* If we are returning a struct, this will already have been added. 261 Otherwise we need to add it because it's always got to be there! */ 262 263 if (cif->rtype->type != FFI_TYPE_STRUCT) 264 cif->bytes += wordsize; 265 266 /* sparc call frames require that space is allocated for 6 args, 267 even if they aren't used. Make that space if necessary. */ 268 269 if (cif->bytes < 4*6+4) 270 cif->bytes = 4*6+4; 271 } 272 else 273 { 274 wordsize = 8; 275 276 /* sparc call frames require that space is allocated for 6 args, 277 even if they aren't used. Make that space if necessary. */ 278 279 if (cif->bytes < 8*6) 280 cif->bytes = 8*6; 281 } 282 283 /* Adjust cif->bytes. to include 16 words for the window save area, 284 and maybe the struct/union return pointer area, */ 285 286 cif->bytes += 16 * wordsize; 287 288 /* The stack must be 2 word aligned, so round bytes up 289 appropriately. */ 290 291 cif->bytes = ALIGN(cif->bytes, 2 * wordsize); 292 293 /* Set the return type flag */ 294 switch (cif->rtype->type) 295 { 296 case FFI_TYPE_VOID: 297 case FFI_TYPE_FLOAT: 298 case FFI_TYPE_DOUBLE: 299 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 300 case FFI_TYPE_LONGDOUBLE: 301 #endif 302 cif->flags = cif->rtype->type; 303 break; 304 305 case FFI_TYPE_STRUCT: 306 if (cif->abi == FFI_V9 && cif->rtype->size > 32) 307 cif->flags = FFI_TYPE_VOID; 308 else 309 cif->flags = FFI_TYPE_STRUCT; 310 break; 311 312 case FFI_TYPE_SINT8: 313 case FFI_TYPE_UINT8: 314 case FFI_TYPE_SINT16: 315 case FFI_TYPE_UINT16: 316 if (cif->abi == FFI_V9) 317 cif->flags = FFI_TYPE_INT; 318 else 319 cif->flags = cif->rtype->type; 320 break; 321 322 case FFI_TYPE_SINT64: 323 case FFI_TYPE_UINT64: 324 if (cif->abi == FFI_V9) 325 cif->flags = FFI_TYPE_INT; 326 else 327 cif->flags = FFI_TYPE_SINT64; 328 break; 329 330 default: 331 cif->flags = FFI_TYPE_INT; 332 break; 333 } 334 return FFI_OK; 335 } 336 337 int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt) 338 { 339 ffi_type **ptr = &arg->elements[0]; 340 341 while (*ptr != NULL) 342 { 343 if (off & ((*ptr)->alignment - 1)) 344 off = ALIGN(off, (*ptr)->alignment); 345 346 switch ((*ptr)->type) 347 { 348 case FFI_TYPE_STRUCT: 349 off = ffi_v9_layout_struct(*ptr, off, ret, intg, flt); 350 off = ALIGN(off, FFI_SIZEOF_ARG); 351 break; 352 case FFI_TYPE_FLOAT: 353 case FFI_TYPE_DOUBLE: 354 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 355 case FFI_TYPE_LONGDOUBLE: 356 #endif 357 memmove(ret + off, flt + off, (*ptr)->size); 358 off += (*ptr)->size; 359 break; 360 default: 361 memmove(ret + off, intg + off, (*ptr)->size); 362 off += (*ptr)->size; 363 break; 364 } 365 ptr++; 366 } 367 return off; 368 } 369 370 371 #ifdef SPARC64 372 extern int ffi_call_v9(void *, extended_cif *, unsigned, 373 unsigned, unsigned *, void (*fn)(void)); 374 #else 375 extern int ffi_call_v8(void *, extended_cif *, unsigned, 376 unsigned, unsigned *, void (*fn)(void)); 377 #endif 378 379 #ifndef __GNUC__ 380 void ffi_flush_icache (void *, size_t); 381 #endif 382 383 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 384 { 385 extended_cif ecif; 386 void *rval = rvalue; 387 388 ecif.cif = cif; 389 ecif.avalue = avalue; 390 391 /* If the return value is a struct and we don't have a return */ 392 /* value address then we need to make one */ 393 394 ecif.rvalue = rvalue; 395 if (cif->rtype->type == FFI_TYPE_STRUCT) 396 { 397 if (cif->rtype->size <= 32) 398 rval = alloca(64); 399 else 400 { 401 rval = NULL; 402 if (rvalue == NULL) 403 ecif.rvalue = alloca(cif->rtype->size); 404 } 405 } 406 407 switch (cif->abi) 408 { 409 case FFI_V8: 410 #ifdef SPARC64 411 /* We don't yet support calling 32bit code from 64bit */ 412 FFI_ASSERT(0); 413 #else 414 if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT 415 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 416 || cif->flags == FFI_TYPE_LONGDOUBLE 417 #endif 418 )) 419 { 420 /* For v8, we need an "unimp" with size of returning struct */ 421 /* behind "call", so we alloc some executable space for it. */ 422 /* l7 is used, we need to make sure v8.S doesn't use %l7. */ 423 unsigned int *call_struct = NULL; 424 ffi_closure_alloc(32, (void **)&call_struct); 425 if (call_struct) 426 { 427 unsigned long f = (unsigned long)fn; 428 call_struct[0] = 0xae10001f; /* mov %i7, %l7 */ 429 call_struct[1] = 0xbe10000f; /* mov %o7, %i7 */ 430 call_struct[2] = 0x03000000 | f >> 10; /* sethi %hi(fn), %g1 */ 431 call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */ 432 call_struct[4] = 0x01000000; /* nop */ 433 if (cif->rtype->size < 0x7f) 434 call_struct[5] = cif->rtype->size; /* unimp */ 435 else 436 call_struct[5] = 0x01000000; /* nop */ 437 call_struct[6] = 0x81c7e008; /* ret */ 438 call_struct[7] = 0xbe100017; /* mov %l7, %i7 */ 439 #ifdef __GNUC__ 440 asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : : 441 "r" (call_struct) : "memory"); 442 /* SPARC v8 requires 5 instructions for flush to be visible */ 443 asm volatile ("nop; nop; nop; nop; nop"); 444 #else 445 ffi_flush_icache (call_struct, 32); 446 #endif 447 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes, 448 cif->flags, rvalue, call_struct); 449 ffi_closure_free(call_struct); 450 } 451 else 452 { 453 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes, 454 cif->flags, rvalue, fn); 455 } 456 } 457 else 458 { 459 ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes, 460 cif->flags, rvalue, fn); 461 } 462 #endif 463 break; 464 case FFI_V9: 465 #ifdef SPARC64 466 ffi_call_v9(ffi_prep_args_v9, &ecif, cif->bytes, 467 cif->flags, rval, fn); 468 if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT) 469 ffi_v9_layout_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32); 470 #else 471 /* And vice versa */ 472 FFI_ASSERT(0); 473 #endif 474 break; 475 default: 476 FFI_ASSERT(0); 477 break; 478 } 479 } 480 481 482 #ifdef SPARC64 483 extern void ffi_closure_v9(void); 484 #else 485 extern void ffi_closure_v8(void); 486 #endif 487 488 ffi_status 489 ffi_prep_closure_loc (ffi_closure* closure, 490 ffi_cif* cif, 491 void (*fun)(ffi_cif*, void*, void**, void*), 492 void *user_data, 493 void *codeloc) 494 { 495 unsigned int *tramp = (unsigned int *) &closure->tramp[0]; 496 unsigned long fn; 497 #ifdef SPARC64 498 /* Trampoline address is equal to the closure address. We take advantage 499 of that to reduce the trampoline size by 8 bytes. */ 500 if (cif->abi != FFI_V9) 501 return FFI_BAD_ABI; 502 fn = (unsigned long) ffi_closure_v9; 503 tramp[0] = 0x83414000; /* rd %pc, %g1 */ 504 tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */ 505 tramp[2] = 0x81c14000; /* jmp %g5 */ 506 tramp[3] = 0x01000000; /* nop */ 507 *((unsigned long *) &tramp[4]) = fn; 508 #else 509 unsigned long ctx = (unsigned long) codeloc; 510 if (cif->abi != FFI_V8) 511 return FFI_BAD_ABI; 512 fn = (unsigned long) ffi_closure_v8; 513 tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */ 514 tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */ 515 tramp[2] = 0x81c06000 | (fn & 0x3ff); /* jmp %g1+%lo(fn) */ 516 tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or %g2, %lo(ctx) */ 517 #endif 518 519 closure->cif = cif; 520 closure->fun = fun; 521 closure->user_data = user_data; 522 523 /* Flush the Icache. closure is 8 bytes aligned. */ 524 #ifdef __GNUC__ 525 #ifdef SPARC64 526 asm volatile ("flush %0; flush %0+8" : : "r" (closure) : "memory"); 527 #else 528 asm volatile ("iflush %0; iflush %0+8" : : "r" (closure) : "memory"); 529 /* SPARC v8 requires 5 instructions for flush to be visible */ 530 asm volatile ("nop; nop; nop; nop; nop"); 531 #endif 532 #else 533 ffi_flush_icache (closure, 16); 534 #endif 535 536 return FFI_OK; 537 } 538 539 int 540 ffi_closure_sparc_inner_v8(ffi_closure *closure, 541 void *rvalue, unsigned long *gpr, unsigned long *scratch) 542 { 543 ffi_cif *cif; 544 ffi_type **arg_types; 545 void **avalue; 546 int i, argn; 547 548 cif = closure->cif; 549 arg_types = cif->arg_types; 550 avalue = alloca(cif->nargs * sizeof(void *)); 551 552 /* Copy the caller's structure return address so that the closure 553 returns the data directly to the caller. */ 554 if (cif->flags == FFI_TYPE_STRUCT 555 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 556 || cif->flags == FFI_TYPE_LONGDOUBLE 557 #endif 558 ) 559 rvalue = (void *) gpr[0]; 560 561 /* Always skip the structure return address. */ 562 argn = 1; 563 564 /* Grab the addresses of the arguments from the stack frame. */ 565 for (i = 0; i < cif->nargs; i++) 566 { 567 if (arg_types[i]->type == FFI_TYPE_STRUCT 568 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 569 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE 570 #endif 571 ) 572 { 573 /* Straight copy of invisible reference. */ 574 avalue[i] = (void *)gpr[argn++]; 575 } 576 else if ((arg_types[i]->type == FFI_TYPE_DOUBLE 577 || arg_types[i]->type == FFI_TYPE_SINT64 578 || arg_types[i]->type == FFI_TYPE_UINT64) 579 /* gpr is 8-byte aligned. */ 580 && (argn % 2) != 0) 581 { 582 /* Align on a 8-byte boundary. */ 583 scratch[0] = gpr[argn]; 584 scratch[1] = gpr[argn+1]; 585 avalue[i] = scratch; 586 scratch -= 2; 587 argn += 2; 588 } 589 else 590 { 591 /* Always right-justify. */ 592 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; 593 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size; 594 } 595 } 596 597 /* Invoke the closure. */ 598 (closure->fun) (cif, rvalue, avalue, closure->user_data); 599 600 /* Tell ffi_closure_sparc how to perform return type promotions. */ 601 return cif->rtype->type; 602 } 603 604 int 605 ffi_closure_sparc_inner_v9(ffi_closure *closure, 606 void *rvalue, unsigned long *gpr, double *fpr) 607 { 608 ffi_cif *cif; 609 ffi_type **arg_types; 610 void **avalue; 611 int i, argn, fp_slot_max; 612 613 cif = closure->cif; 614 arg_types = cif->arg_types; 615 avalue = alloca(cif->nargs * sizeof(void *)); 616 617 /* Copy the caller's structure return address so that the closure 618 returns the data directly to the caller. */ 619 if (cif->flags == FFI_TYPE_VOID 620 && cif->rtype->type == FFI_TYPE_STRUCT) 621 { 622 rvalue = (void *) gpr[0]; 623 /* Skip the structure return address. */ 624 argn = 1; 625 } 626 else 627 argn = 0; 628 629 fp_slot_max = 16 - argn; 630 631 /* Grab the addresses of the arguments from the stack frame. */ 632 for (i = 0; i < cif->nargs; i++) 633 { 634 if (arg_types[i]->type == FFI_TYPE_STRUCT) 635 { 636 if (arg_types[i]->size > 16) 637 { 638 /* Straight copy of invisible reference. */ 639 avalue[i] = (void *)gpr[argn++]; 640 } 641 else 642 { 643 /* Left-justify. */ 644 ffi_v9_layout_struct(arg_types[i], 645 0, 646 (char *) &gpr[argn], 647 (char *) &gpr[argn], 648 (char *) &fpr[argn]); 649 avalue[i] = &gpr[argn]; 650 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; 651 } 652 } 653 else 654 { 655 /* Right-justify. */ 656 argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; 657 658 /* Align on a 16-byte boundary. */ 659 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 660 if (arg_types[i]->type == FFI_TYPE_LONGDOUBLE && (argn % 2) != 0) 661 argn++; 662 #endif 663 if (i < fp_slot_max 664 && (arg_types[i]->type == FFI_TYPE_FLOAT 665 || arg_types[i]->type == FFI_TYPE_DOUBLE 666 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE 667 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE 668 #endif 669 )) 670 avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size; 671 else 672 avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size; 673 } 674 } 675 676 /* Invoke the closure. */ 677 (closure->fun) (cif, rvalue, avalue, closure->user_data); 678 679 /* Tell ffi_closure_sparc how to perform return type promotions. */ 680 return cif->rtype->type; 681 } 682