1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 1998 Cygnus Solutions
3 Copyright (c) 2004 Simon Posnjak
4 Copyright (c) 2005 Axis Communications AB
6 CRIS Foreign Function Interface
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 OTHER DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
29 #include <ffi_common.h>
31 #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
34 initialize_aggregate_packed_struct (ffi_type * arg)
38 FFI_ASSERT (arg != NULL);
40 FFI_ASSERT (arg->elements != NULL);
41 FFI_ASSERT (arg->size == 0);
42 FFI_ASSERT (arg->alignment == 0);
44 ptr = &(arg->elements[0]);
46 while ((*ptr) != NULL)
48 if (((*ptr)->size == 0)
49 && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
50 return FFI_BAD_TYPEDEF;
52 FFI_ASSERT (ffi_type_test ((*ptr)));
54 arg->size += (*ptr)->size;
56 arg->alignment = (arg->alignment > (*ptr)->alignment) ?
57 arg->alignment : (*ptr)->alignment;
63 return FFI_BAD_TYPEDEF;
69 ffi_prep_args (char *stack, extended_cif * ecif)
72 unsigned int struct_count = 0;
79 p_argv = ecif->avalue;
81 for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
82 (i != 0); i--, p_arg++)
86 switch ((*p_arg)->type)
93 memcpy (argp, *p_argv, z);
98 memcpy (argp, *p_argv, z);
103 unsigned int uiLocOnStack;
105 uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
106 struct_count = struct_count + (*p_arg)->size;
107 *(unsigned int *) argp =
108 (unsigned int) (UINT32 *) (stack + uiLocOnStack);
109 memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
115 if (z < sizeof (int))
117 switch ((*p_arg)->type)
120 *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
124 *(unsigned int *) argp =
125 (unsigned int) *(UINT8 *) (*p_argv);
128 case FFI_TYPE_SINT16:
129 *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
132 case FFI_TYPE_UINT16:
133 *(unsigned int *) argp =
134 (unsigned int) *(UINT16 *) (*p_argv);
142 else if (z == sizeof (int))
143 *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
145 memcpy (argp, *p_argv, z);
152 return (struct_count);
156 ffi_prep_cif (ffi_cif * cif,
157 ffi_abi abi, unsigned int nargs,
158 ffi_type * rtype, ffi_type ** atypes)
164 FFI_ASSERT (cif != NULL);
165 FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
168 cif->arg_types = atypes;
174 if ((cif->rtype->size == 0)
175 && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
176 return FFI_BAD_TYPEDEF;
178 FFI_ASSERT_VALID_TYPE (cif->rtype);
180 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
182 if (((*ptr)->size == 0)
183 && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
184 return FFI_BAD_TYPEDEF;
186 FFI_ASSERT_VALID_TYPE (*ptr);
188 if (((*ptr)->alignment - 1) & bytes)
189 bytes = ALIGN (bytes, (*ptr)->alignment);
190 if ((*ptr)->type == FFI_TYPE_STRUCT)
192 if ((*ptr)->size > 8)
194 bytes += (*ptr)->size;
195 bytes += sizeof (void *);
199 if ((*ptr)->size > 4)
206 bytes += STACK_ARG_SIZE ((*ptr)->size);
211 return ffi_prep_cif_machdep (cif);
215 ffi_prep_cif_machdep (ffi_cif * cif)
217 switch (cif->rtype->type)
220 case FFI_TYPE_STRUCT:
222 case FFI_TYPE_DOUBLE:
223 case FFI_TYPE_SINT64:
224 case FFI_TYPE_UINT64:
225 cif->flags = (unsigned) cif->rtype->type;
229 cif->flags = FFI_TYPE_INT;
236 extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
238 unsigned, unsigned, unsigned *, void (*fn) ())
239 __attribute__ ((__visibility__ ("hidden")));
242 ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
247 ecif.avalue = avalue;
249 if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
251 ecif.rvalue = alloca (cif->rtype->size);
254 ecif.rvalue = rvalue;
259 ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
260 cif->flags, ecif.rvalue, fn);
268 /* Because the following variables are not exported outside libffi, we
271 /* Assembly code for the jump stub. */
272 extern const char ffi_cris_trampoline_template[]
273 __attribute__ ((__visibility__ ("hidden")));
275 /* Offset into ffi_cris_trampoline_template of where to put the
276 ffi_prep_closure_inner function. */
277 extern const int ffi_cris_trampoline_fn_offset
278 __attribute__ ((__visibility__ ("hidden")));
280 /* Offset into ffi_cris_trampoline_template of where to put the
282 extern const int ffi_cris_trampoline_closure_offset
283 __attribute__ ((__visibility__ ("hidden")));
285 /* This function is sibling-called (jumped to) by the closure
286 trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
287 PARAMS[4] to simplify handling of a straddling parameter. A copy
288 of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
289 put at the appropriate place in CLOSURE which is then executed and
290 the return value is passed back to the caller. */
292 static unsigned long long
293 ffi_prep_closure_inner (void **params, ffi_closure* closure)
295 char *register_args = (char *) params;
296 void *struct_ret = params[5];
297 char *stack_args = params[6];
298 char *ptr = register_args;
299 ffi_cif *cif = closure->cif;
300 ffi_type **arg_types = cif->arg_types;
302 /* Max room needed is number of arguments as 64-bit values. */
303 void **avalue = alloca (closure->cif->nargs * sizeof(void *));
308 /* Find the address of each argument. */
309 for (i = 0, doing_regs = 1; i < cif->nargs; i++)
311 /* Types up to and including 8 bytes go by-value. */
312 if (arg_types[i]->size <= 4)
317 else if (arg_types[i]->size <= 8)
324 FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
326 /* Passed by-reference, so copy the pointer. */
327 avalue[i] = *(void **) ptr;
331 /* If we've handled more arguments than fit in registers, start
332 looking at the those passed on the stack. Step over the
333 first one if we had a straddling parameter. */
334 if (doing_regs && ptr >= register_args + 4*4)
336 ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
341 /* Invoke the closure. */
344 cif->rtype->type == FFI_TYPE_STRUCT
345 /* The caller allocated space for the return
346 structure, and passed a pointer to this space in
350 /* We take advantage of being able to ignore that
351 the high part isn't set if the return value is
352 not in R10:R11, but in R10 only. */
355 avalue, closure->user_data);
360 /* API function: Prepare the trampoline. */
363 ffi_prep_closure (ffi_closure* closure,
365 void (*fun)(ffi_cif *, void *, void **, void*),
368 void *innerfn = ffi_prep_closure_inner;
369 FFI_ASSERT (cif->abi == FFI_SYSV);
371 closure->user_data = user_data;
373 memcpy (closure->tramp, ffi_cris_trampoline_template,
374 FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
375 memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
376 &innerfn, sizeof (void *));
377 memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
378 &closure, sizeof (void *));