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