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 *));