1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2000, 2007 Software AG
3 Copyright (c) 2008 Red Hat, Inc
4
5 S390 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, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25 ----------------------------------------------------------------------- */
26 /*====================================================================*/
27 /* Includes */
28 /* -------- */
29 /*====================================================================*/
30
31 #include <ffi.h>
32 #include <ffi_common.h>
33 #include <stdint.h>
34 #include "internal.h"
35
36 /*====================== End of Includes =============================*/
37
38 /*====================================================================*/
39 /* Defines */
40 /* ------- */
41 /*====================================================================*/
42
43 /* Maximum number of GPRs available for argument passing. */
44 #define MAX_GPRARGS 5
45
46 /* Maximum number of FPRs available for argument passing. */
47 #ifdef __s390x__
48 #define MAX_FPRARGS 4
49 #else
50 #define MAX_FPRARGS 2
51 #endif
52
53 /* Round to multiple of 16. */
54 #define ROUND_SIZE(size) (((size) + 15) & ~15)
55
56 /*===================== End of Defines ===============================*/
57
58 /*====================================================================*/
59 /* Externals */
60 /* --------- */
61 /*====================================================================*/
62
63 struct call_frame
64 {
65 void *back_chain;
66 void *eos;
67 unsigned long gpr_args[5];
68 unsigned long gpr_save[9];
69 unsigned long long fpr_args[4];
70 };
71
72 extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *,
73 void (*fn)(void), void *);
74
75 extern void ffi_closure_SYSV(void);
76 extern void ffi_go_closure_SYSV(void);
77
78 /*====================== End of Externals ============================*/
79
80 /*====================================================================*/
81 /* */
82 /* Name - ffi_check_struct_type. */
83 /* */
84 /* Function - Determine if a structure can be passed within a */
85 /* general purpose or floating point register. */
86 /* */
87 /*====================================================================*/
88
89 static int
ffi_check_struct_type(ffi_type * arg)90 ffi_check_struct_type (ffi_type *arg)
91 {
92 size_t size = arg->size;
93
94 /* If the struct has just one element, look at that element
95 to find out whether to consider the struct as floating point. */
96 while (arg->type == FFI_TYPE_STRUCT
97 && arg->elements[0] && !arg->elements[1])
98 arg = arg->elements[0];
99
100 /* Structs of size 1, 2, 4, and 8 are passed in registers,
101 just like the corresponding int/float types. */
102 switch (size)
103 {
104 case 1:
105 return FFI_TYPE_UINT8;
106
107 case 2:
108 return FFI_TYPE_UINT16;
109
110 case 4:
111 if (arg->type == FFI_TYPE_FLOAT)
112 return FFI_TYPE_FLOAT;
113 else
114 return FFI_TYPE_UINT32;
115
116 case 8:
117 if (arg->type == FFI_TYPE_DOUBLE)
118 return FFI_TYPE_DOUBLE;
119 else
120 return FFI_TYPE_UINT64;
121
122 default:
123 break;
124 }
125
126 /* Other structs are passed via a pointer to the data. */
127 return FFI_TYPE_POINTER;
128 }
129
130 /*======================== End of Routine ============================*/
131
132 /*====================================================================*/
133 /* */
134 /* Name - ffi_prep_cif_machdep. */
135 /* */
136 /* Function - Perform machine dependent CIF processing. */
137 /* */
138 /*====================================================================*/
139
140 ffi_status FFI_HIDDEN
ffi_prep_cif_machdep(ffi_cif * cif)141 ffi_prep_cif_machdep(ffi_cif *cif)
142 {
143 size_t struct_size = 0;
144 int n_gpr = 0;
145 int n_fpr = 0;
146 int n_ov = 0;
147
148 ffi_type **ptr;
149 int i;
150
151 /* Determine return value handling. */
152
153 switch (cif->rtype->type)
154 {
155 /* Void is easy. */
156 case FFI_TYPE_VOID:
157 cif->flags = FFI390_RET_VOID;
158 break;
159
160 /* Structures and complex are returned via a hidden pointer. */
161 case FFI_TYPE_STRUCT:
162 case FFI_TYPE_COMPLEX:
163 cif->flags = FFI390_RET_STRUCT;
164 n_gpr++; /* We need one GPR to pass the pointer. */
165 break;
166
167 /* Floating point values are returned in fpr 0. */
168 case FFI_TYPE_FLOAT:
169 cif->flags = FFI390_RET_FLOAT;
170 break;
171
172 case FFI_TYPE_DOUBLE:
173 cif->flags = FFI390_RET_DOUBLE;
174 break;
175
176 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
177 case FFI_TYPE_LONGDOUBLE:
178 cif->flags = FFI390_RET_STRUCT;
179 n_gpr++;
180 break;
181 #endif
182 /* Integer values are returned in gpr 2 (and gpr 3
183 for 64-bit values on 31-bit machines). */
184 case FFI_TYPE_UINT64:
185 case FFI_TYPE_SINT64:
186 cif->flags = FFI390_RET_INT64;
187 break;
188
189 case FFI_TYPE_POINTER:
190 case FFI_TYPE_INT:
191 case FFI_TYPE_UINT32:
192 case FFI_TYPE_SINT32:
193 case FFI_TYPE_UINT16:
194 case FFI_TYPE_SINT16:
195 case FFI_TYPE_UINT8:
196 case FFI_TYPE_SINT8:
197 /* These are to be extended to word size. */
198 #ifdef __s390x__
199 cif->flags = FFI390_RET_INT64;
200 #else
201 cif->flags = FFI390_RET_INT32;
202 #endif
203 break;
204
205 default:
206 FFI_ASSERT (0);
207 break;
208 }
209
210 /* Now for the arguments. */
211
212 for (ptr = cif->arg_types, i = cif->nargs;
213 i > 0;
214 i--, ptr++)
215 {
216 int type = (*ptr)->type;
217
218 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
219 /* 16-byte long double is passed like a struct. */
220 if (type == FFI_TYPE_LONGDOUBLE)
221 type = FFI_TYPE_STRUCT;
222 #endif
223
224 /* Check how a structure type is passed. */
225 if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
226 {
227 if (type == FFI_TYPE_COMPLEX)
228 type = FFI_TYPE_POINTER;
229 else
230 type = ffi_check_struct_type (*ptr);
231
232 /* If we pass the struct via pointer, we must reserve space
233 to copy its data for proper call-by-value semantics. */
234 if (type == FFI_TYPE_POINTER)
235 struct_size += ROUND_SIZE ((*ptr)->size);
236 }
237
238 /* Now handle all primitive int/float data types. */
239 switch (type)
240 {
241 /* The first MAX_FPRARGS floating point arguments
242 go in FPRs, the rest overflow to the stack. */
243
244 case FFI_TYPE_DOUBLE:
245 if (n_fpr < MAX_FPRARGS)
246 n_fpr++;
247 else
248 n_ov += sizeof (double) / sizeof (long);
249 break;
250
251 case FFI_TYPE_FLOAT:
252 if (n_fpr < MAX_FPRARGS)
253 n_fpr++;
254 else
255 n_ov++;
256 break;
257
258 /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
259 if one is still available, or else on the stack. If only one
260 register is free, skip the register (it won't be used for any
261 subsequent argument either). */
262
263 #ifndef __s390x__
264 case FFI_TYPE_UINT64:
265 case FFI_TYPE_SINT64:
266 if (n_gpr == MAX_GPRARGS-1)
267 n_gpr = MAX_GPRARGS;
268 if (n_gpr < MAX_GPRARGS)
269 n_gpr += 2;
270 else
271 n_ov += 2;
272 break;
273 #endif
274
275 /* Everything else is passed in GPRs (until MAX_GPRARGS
276 have been used) or overflows to the stack. */
277
278 default:
279 if (n_gpr < MAX_GPRARGS)
280 n_gpr++;
281 else
282 n_ov++;
283 break;
284 }
285 }
286
287 /* Total stack space as required for overflow arguments
288 and temporary structure copies. */
289
290 cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
291
292 return FFI_OK;
293 }
294
295 /*======================== End of Routine ============================*/
296
297 /*====================================================================*/
298 /* */
299 /* Name - ffi_call. */
300 /* */
301 /* Function - Call the FFI routine. */
302 /* */
303 /*====================================================================*/
304
305 static void
ffi_call_int(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)306 ffi_call_int(ffi_cif *cif,
307 void (*fn)(void),
308 void *rvalue,
309 void **avalue,
310 void *closure)
311 {
312 int ret_type = cif->flags;
313 size_t rsize = 0, bytes = cif->bytes;
314 unsigned char *stack, *p_struct;
315 struct call_frame *frame;
316 unsigned long *p_ov, *p_gpr;
317 unsigned long long *p_fpr;
318 int n_fpr, n_gpr, n_ov, i, n;
319 ffi_type **arg_types;
320
321 FFI_ASSERT (cif->abi == FFI_SYSV);
322
323 /* If we don't have a return value, we need to fake one. */
324 if (rvalue == NULL)
325 {
326 if (ret_type & FFI390_RET_IN_MEM)
327 rsize = cif->rtype->size;
328 else
329 ret_type = FFI390_RET_VOID;
330 }
331
332 /* The stack space will be filled with those areas:
333
334 dummy structure return (highest addresses)
335 FPR argument register save area
336 GPR argument register save area
337 stack frame for ffi_call_SYSV
338 temporary struct copies
339 overflow argument area (lowest addresses)
340
341 We set up the following pointers:
342
343 p_fpr: bottom of the FPR area (growing upwards)
344 p_gpr: bottom of the GPR area (growing upwards)
345 p_ov: bottom of the overflow area (growing upwards)
346 p_struct: top of the struct copy area (growing downwards)
347
348 All areas are kept aligned to twice the word size.
349
350 Note that we're going to create the stack frame for both
351 ffi_call_SYSV _and_ the target function right here. This
352 works because we don't make any function calls with more
353 than 5 arguments (indeed only memcpy and ffi_call_SYSV),
354 and thus we don't have any stacked outgoing parameters. */
355
356 stack = alloca (bytes + sizeof(struct call_frame) + rsize);
357 frame = (struct call_frame *)(stack + bytes);
358 if (rsize)
359 rvalue = frame + 1;
360
361 /* Link the new frame back to the one from this function. */
362 frame->back_chain = __builtin_frame_address (0);
363
364 /* Fill in all of the argument stuff. */
365 p_ov = (unsigned long *)stack;
366 p_struct = (unsigned char *)frame;
367 p_gpr = frame->gpr_args;
368 p_fpr = frame->fpr_args;
369 n_fpr = n_gpr = n_ov = 0;
370
371 /* If we returning a structure then we set the first parameter register
372 to the address of where we are returning this structure. */
373 if (cif->flags & FFI390_RET_IN_MEM)
374 p_gpr[n_gpr++] = (uintptr_t) rvalue;
375
376 /* Now for the arguments. */
377 arg_types = cif->arg_types;
378 for (i = 0, n = cif->nargs; i < n; ++i)
379 {
380 ffi_type *ty = arg_types[i];
381 void *arg = avalue[i];
382 int type = ty->type;
383 ffi_arg val;
384
385 restart:
386 switch (type)
387 {
388 case FFI_TYPE_SINT8:
389 val = *(SINT8 *)arg;
390 goto do_int;
391 case FFI_TYPE_UINT8:
392 val = *(UINT8 *)arg;
393 goto do_int;
394 case FFI_TYPE_SINT16:
395 val = *(SINT16 *)arg;
396 goto do_int;
397 case FFI_TYPE_UINT16:
398 val = *(UINT16 *)arg;
399 goto do_int;
400 case FFI_TYPE_INT:
401 case FFI_TYPE_SINT32:
402 val = *(SINT32 *)arg;
403 goto do_int;
404 case FFI_TYPE_UINT32:
405 val = *(UINT32 *)arg;
406 goto do_int;
407 case FFI_TYPE_POINTER:
408 val = *(uintptr_t *)arg;
409 do_int:
410 *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;
411 break;
412
413 case FFI_TYPE_UINT64:
414 case FFI_TYPE_SINT64:
415 #ifdef __s390x__
416 val = *(UINT64 *)arg;
417 goto do_int;
418 #else
419 if (n_gpr == MAX_GPRARGS-1)
420 n_gpr = MAX_GPRARGS;
421 if (n_gpr < MAX_GPRARGS)
422 p_gpr[n_gpr++] = ((UINT32 *) arg)[0],
423 p_gpr[n_gpr++] = ((UINT32 *) arg)[1];
424 else
425 p_ov[n_ov++] = ((UINT32 *) arg)[0],
426 p_ov[n_ov++] = ((UINT32 *) arg)[1];
427 #endif
428 break;
429
430 case FFI_TYPE_DOUBLE:
431 if (n_fpr < MAX_FPRARGS)
432 p_fpr[n_fpr++] = *(UINT64 *) arg;
433 else
434 {
435 #ifdef __s390x__
436 p_ov[n_ov++] = *(UINT64 *) arg;
437 #else
438 p_ov[n_ov++] = ((UINT32 *) arg)[0],
439 p_ov[n_ov++] = ((UINT32 *) arg)[1];
440 #endif
441 }
442 break;
443
444 case FFI_TYPE_FLOAT:
445 val = *(UINT32 *)arg;
446 if (n_fpr < MAX_FPRARGS)
447 p_fpr[n_fpr++] = (UINT64)val << 32;
448 else
449 p_ov[n_ov++] = val;
450 break;
451
452 case FFI_TYPE_STRUCT:
453 /* Check how a structure type is passed. */
454 type = ffi_check_struct_type (ty);
455 /* Some structures are passed via a type they contain. */
456 if (type != FFI_TYPE_POINTER)
457 goto restart;
458 /* ... otherwise, passed by reference. fallthru. */
459
460 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
461 case FFI_TYPE_LONGDOUBLE:
462 /* 16-byte long double is passed via reference. */
463 #endif
464 case FFI_TYPE_COMPLEX:
465 /* Complex types are passed via reference. */
466 p_struct -= ROUND_SIZE (ty->size);
467 memcpy (p_struct, arg, ty->size);
468 val = (uintptr_t)p_struct;
469 goto do_int;
470
471 default:
472 FFI_ASSERT (0);
473 break;
474 }
475 }
476
477 ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);
478 }
479
480 void
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)481 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
482 {
483 ffi_call_int(cif, fn, rvalue, avalue, NULL);
484 }
485
486 void
ffi_call_go(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue,void * closure)487 ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
488 void **avalue, void *closure)
489 {
490 ffi_call_int(cif, fn, rvalue, avalue, closure);
491 }
492
493 /*======================== End of Routine ============================*/
494
495 /*====================================================================*/
496 /* */
497 /* Name - ffi_closure_helper_SYSV. */
498 /* */
499 /* Function - Call a FFI closure target function. */
500 /* */
501 /*====================================================================*/
502
503 void FFI_HIDDEN
ffi_closure_helper_SYSV(ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,unsigned long * p_gpr,unsigned long long * p_fpr,unsigned long * p_ov)504 ffi_closure_helper_SYSV (ffi_cif *cif,
505 void (*fun)(ffi_cif*,void*,void**,void*),
506 void *user_data,
507 unsigned long *p_gpr,
508 unsigned long long *p_fpr,
509 unsigned long *p_ov)
510 {
511 unsigned long long ret_buffer;
512
513 void *rvalue = &ret_buffer;
514 void **avalue;
515 void **p_arg;
516
517 int n_gpr = 0;
518 int n_fpr = 0;
519 int n_ov = 0;
520
521 ffi_type **ptr;
522 int i;
523
524 /* Allocate buffer for argument list pointers. */
525 p_arg = avalue = alloca (cif->nargs * sizeof (void *));
526
527 /* If we returning a structure, pass the structure address
528 directly to the target function. Otherwise, have the target
529 function store the return value to the GPR save area. */
530 if (cif->flags & FFI390_RET_IN_MEM)
531 rvalue = (void *) p_gpr[n_gpr++];
532
533 /* Now for the arguments. */
534 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
535 {
536 int deref_struct_pointer = 0;
537 int type = (*ptr)->type;
538
539 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
540 /* 16-byte long double is passed like a struct. */
541 if (type == FFI_TYPE_LONGDOUBLE)
542 type = FFI_TYPE_STRUCT;
543 #endif
544
545 /* Check how a structure type is passed. */
546 if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
547 {
548 if (type == FFI_TYPE_COMPLEX)
549 type = FFI_TYPE_POINTER;
550 else
551 type = ffi_check_struct_type (*ptr);
552
553 /* If we pass the struct via pointer, remember to
554 retrieve the pointer later. */
555 if (type == FFI_TYPE_POINTER)
556 deref_struct_pointer = 1;
557 }
558
559 /* Pointers are passed like UINTs of the same size. */
560 if (type == FFI_TYPE_POINTER)
561 {
562 #ifdef __s390x__
563 type = FFI_TYPE_UINT64;
564 #else
565 type = FFI_TYPE_UINT32;
566 #endif
567 }
568
569 /* Now handle all primitive int/float data types. */
570 switch (type)
571 {
572 case FFI_TYPE_DOUBLE:
573 if (n_fpr < MAX_FPRARGS)
574 *p_arg = &p_fpr[n_fpr++];
575 else
576 *p_arg = &p_ov[n_ov],
577 n_ov += sizeof (double) / sizeof (long);
578 break;
579
580 case FFI_TYPE_FLOAT:
581 if (n_fpr < MAX_FPRARGS)
582 *p_arg = &p_fpr[n_fpr++];
583 else
584 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
585 break;
586
587 case FFI_TYPE_UINT64:
588 case FFI_TYPE_SINT64:
589 #ifdef __s390x__
590 if (n_gpr < MAX_GPRARGS)
591 *p_arg = &p_gpr[n_gpr++];
592 else
593 *p_arg = &p_ov[n_ov++];
594 #else
595 if (n_gpr == MAX_GPRARGS-1)
596 n_gpr = MAX_GPRARGS;
597 if (n_gpr < MAX_GPRARGS)
598 *p_arg = &p_gpr[n_gpr], n_gpr += 2;
599 else
600 *p_arg = &p_ov[n_ov], n_ov += 2;
601 #endif
602 break;
603
604 case FFI_TYPE_INT:
605 case FFI_TYPE_UINT32:
606 case FFI_TYPE_SINT32:
607 if (n_gpr < MAX_GPRARGS)
608 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
609 else
610 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
611 break;
612
613 case FFI_TYPE_UINT16:
614 case FFI_TYPE_SINT16:
615 if (n_gpr < MAX_GPRARGS)
616 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
617 else
618 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
619 break;
620
621 case FFI_TYPE_UINT8:
622 case FFI_TYPE_SINT8:
623 if (n_gpr < MAX_GPRARGS)
624 *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
625 else
626 *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
627 break;
628
629 default:
630 FFI_ASSERT (0);
631 break;
632 }
633
634 /* If this is a struct passed via pointer, we need to
635 actually retrieve that pointer. */
636 if (deref_struct_pointer)
637 *p_arg = *(void **)*p_arg;
638 }
639
640
641 /* Call the target function. */
642 (fun) (cif, rvalue, avalue, user_data);
643
644 /* Convert the return value. */
645 switch (cif->rtype->type)
646 {
647 /* Void is easy, and so is struct. */
648 case FFI_TYPE_VOID:
649 case FFI_TYPE_STRUCT:
650 case FFI_TYPE_COMPLEX:
651 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
652 case FFI_TYPE_LONGDOUBLE:
653 #endif
654 break;
655
656 /* Floating point values are returned in fpr 0. */
657 case FFI_TYPE_FLOAT:
658 p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
659 break;
660
661 case FFI_TYPE_DOUBLE:
662 p_fpr[0] = *(unsigned long long *) rvalue;
663 break;
664
665 /* Integer values are returned in gpr 2 (and gpr 3
666 for 64-bit values on 31-bit machines). */
667 case FFI_TYPE_UINT64:
668 case FFI_TYPE_SINT64:
669 #ifdef __s390x__
670 p_gpr[0] = *(unsigned long *) rvalue;
671 #else
672 p_gpr[0] = ((unsigned long *) rvalue)[0],
673 p_gpr[1] = ((unsigned long *) rvalue)[1];
674 #endif
675 break;
676
677 case FFI_TYPE_POINTER:
678 case FFI_TYPE_UINT32:
679 case FFI_TYPE_UINT16:
680 case FFI_TYPE_UINT8:
681 p_gpr[0] = *(unsigned long *) rvalue;
682 break;
683
684 case FFI_TYPE_INT:
685 case FFI_TYPE_SINT32:
686 case FFI_TYPE_SINT16:
687 case FFI_TYPE_SINT8:
688 p_gpr[0] = *(signed long *) rvalue;
689 break;
690
691 default:
692 FFI_ASSERT (0);
693 break;
694 }
695 }
696
697 /*======================== End of Routine ============================*/
698
699 /*====================================================================*/
700 /* */
701 /* Name - ffi_prep_closure_loc. */
702 /* */
703 /* Function - Prepare a FFI closure. */
704 /* */
705 /*====================================================================*/
706
707 ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)708 ffi_prep_closure_loc (ffi_closure *closure,
709 ffi_cif *cif,
710 void (*fun) (ffi_cif *, void *, void **, void *),
711 void *user_data,
712 void *codeloc)
713 {
714 static unsigned short const template[] = {
715 0x0d10, /* basr %r1,0 */
716 #ifndef __s390x__
717 0x9801, 0x1006, /* lm %r0,%r1,6(%r1) */
718 #else
719 0xeb01, 0x100e, 0x0004, /* lmg %r0,%r1,14(%r1) */
720 #endif
721 0x07f1 /* br %r1 */
722 };
723
724 unsigned long *tramp = (unsigned long *)&closure->tramp;
725
726 if (cif->abi != FFI_SYSV)
727 return FFI_BAD_ABI;
728
729 memcpy (tramp, template, sizeof(template));
730 tramp[2] = (unsigned long)codeloc;
731 tramp[3] = (unsigned long)&ffi_closure_SYSV;
732
733 closure->cif = cif;
734 closure->fun = fun;
735 closure->user_data = user_data;
736
737 return FFI_OK;
738 }
739
740 /*======================== End of Routine ============================*/
741
742 /* Build a Go language closure. */
743
744 ffi_status
ffi_prep_go_closure(ffi_go_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *))745 ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
746 void (*fun)(ffi_cif*,void*,void**,void*))
747 {
748 if (cif->abi != FFI_SYSV)
749 return FFI_BAD_ABI;
750
751 closure->tramp = ffi_go_closure_SYSV;
752 closure->cif = cif;
753 closure->fun = fun;
754
755 return FFI_OK;
756 }
757