ยปCore Development>Code coverage>Modules/_ctypes/libffi/src/cris/ffi.c

Python code coverage for Modules/_ctypes/libffi/src/cris/ffi.c

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 1998 Cygnus Solutions
3n/a Copyright (c) 2004 Simon Posnjak
4n/a Copyright (c) 2005 Axis Communications AB
5n/a Copyright (C) 2007 Free Software Foundation, Inc.
6n/a
7n/a CRIS Foreign Function Interface
8n/a
9n/a Permission is hereby granted, free of charge, to any person obtaining
10n/a a copy of this software and associated documentation files (the
11n/a ``Software''), to deal in the Software without restriction, including
12n/a without limitation the rights to use, copy, modify, merge, publish,
13n/a distribute, sublicense, and/or sell copies of the Software, and to
14n/a permit persons to whom the Software is furnished to do so, subject to
15n/a the following conditions:
16n/a
17n/a The above copyright notice and this permission notice shall be included
18n/a in all copies or substantial portions of the Software.
19n/a
20n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
21n/a OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23n/a IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
24n/a OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25n/a ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26n/a OTHER DEALINGS IN THE SOFTWARE.
27n/a ----------------------------------------------------------------------- */
28n/a
29n/a#include <ffi.h>
30n/a#include <ffi_common.h>
31n/a
32n/a#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
33n/a
34n/astatic ffi_status
35n/ainitialize_aggregate_packed_struct (ffi_type * arg)
36n/a{
37n/a ffi_type **ptr;
38n/a
39n/a FFI_ASSERT (arg != NULL);
40n/a
41n/a FFI_ASSERT (arg->elements != NULL);
42n/a FFI_ASSERT (arg->size == 0);
43n/a FFI_ASSERT (arg->alignment == 0);
44n/a
45n/a ptr = &(arg->elements[0]);
46n/a
47n/a while ((*ptr) != NULL)
48n/a {
49n/a if (((*ptr)->size == 0)
50n/a && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
51n/a return FFI_BAD_TYPEDEF;
52n/a
53n/a FFI_ASSERT (ffi_type_test ((*ptr)));
54n/a
55n/a arg->size += (*ptr)->size;
56n/a
57n/a arg->alignment = (arg->alignment > (*ptr)->alignment) ?
58n/a arg->alignment : (*ptr)->alignment;
59n/a
60n/a ptr++;
61n/a }
62n/a
63n/a if (arg->size == 0)
64n/a return FFI_BAD_TYPEDEF;
65n/a else
66n/a return FFI_OK;
67n/a}
68n/a
69n/aint
70n/affi_prep_args (char *stack, extended_cif * ecif)
71n/a{
72n/a unsigned int i;
73n/a unsigned int struct_count = 0;
74n/a void **p_argv;
75n/a char *argp;
76n/a ffi_type **p_arg;
77n/a
78n/a argp = stack;
79n/a
80n/a p_argv = ecif->avalue;
81n/a
82n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
83n/a (i != 0); i--, p_arg++)
84n/a {
85n/a size_t z;
86n/a
87n/a switch ((*p_arg)->type)
88n/a {
89n/a case FFI_TYPE_STRUCT:
90n/a {
91n/a z = (*p_arg)->size;
92n/a if (z <= 4)
93n/a {
94n/a memcpy (argp, *p_argv, z);
95n/a z = 4;
96n/a }
97n/a else if (z <= 8)
98n/a {
99n/a memcpy (argp, *p_argv, z);
100n/a z = 8;
101n/a }
102n/a else
103n/a {
104n/a unsigned int uiLocOnStack;
105n/a z = sizeof (void *);
106n/a uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
107n/a struct_count = struct_count + (*p_arg)->size;
108n/a *(unsigned int *) argp =
109n/a (unsigned int) (UINT32 *) (stack + uiLocOnStack);
110n/a memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
111n/a }
112n/a break;
113n/a }
114n/a default:
115n/a z = (*p_arg)->size;
116n/a if (z < sizeof (int))
117n/a {
118n/a switch ((*p_arg)->type)
119n/a {
120n/a case FFI_TYPE_SINT8:
121n/a *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
122n/a break;
123n/a
124n/a case FFI_TYPE_UINT8:
125n/a *(unsigned int *) argp =
126n/a (unsigned int) *(UINT8 *) (*p_argv);
127n/a break;
128n/a
129n/a case FFI_TYPE_SINT16:
130n/a *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
131n/a break;
132n/a
133n/a case FFI_TYPE_UINT16:
134n/a *(unsigned int *) argp =
135n/a (unsigned int) *(UINT16 *) (*p_argv);
136n/a break;
137n/a
138n/a default:
139n/a FFI_ASSERT (0);
140n/a }
141n/a z = sizeof (int);
142n/a }
143n/a else if (z == sizeof (int))
144n/a *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
145n/a else
146n/a memcpy (argp, *p_argv, z);
147n/a break;
148n/a }
149n/a p_argv++;
150n/a argp += z;
151n/a }
152n/a
153n/a return (struct_count);
154n/a}
155n/a
156n/affi_status FFI_HIDDEN
157n/affi_prep_cif_core (ffi_cif * cif,
158n/a ffi_abi abi, unsigned int isvariadic,
159n/a unsigned int nfixedargs, unsigned int ntotalargs,
160n/a ffi_type * rtype, ffi_type ** atypes)
161n/a{
162n/a unsigned bytes = 0;
163n/a unsigned int i;
164n/a ffi_type **ptr;
165n/a
166n/a FFI_ASSERT (cif != NULL);
167n/a FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
168n/a FFI_ASSERT(nfixedargs <= ntotalargs);
169n/a FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI);
170n/a
171n/a cif->abi = abi;
172n/a cif->arg_types = atypes;
173n/a cif->nargs = ntotalargs;
174n/a cif->rtype = rtype;
175n/a
176n/a cif->flags = 0;
177n/a
178n/a if ((cif->rtype->size == 0)
179n/a && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
180n/a return FFI_BAD_TYPEDEF;
181n/a
182n/a FFI_ASSERT_VALID_TYPE (cif->rtype);
183n/a
184n/a for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
185n/a {
186n/a if (((*ptr)->size == 0)
187n/a && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
188n/a return FFI_BAD_TYPEDEF;
189n/a
190n/a FFI_ASSERT_VALID_TYPE (*ptr);
191n/a
192n/a if (((*ptr)->alignment - 1) & bytes)
193n/a bytes = ALIGN (bytes, (*ptr)->alignment);
194n/a if ((*ptr)->type == FFI_TYPE_STRUCT)
195n/a {
196n/a if ((*ptr)->size > 8)
197n/a {
198n/a bytes += (*ptr)->size;
199n/a bytes += sizeof (void *);
200n/a }
201n/a else
202n/a {
203n/a if ((*ptr)->size > 4)
204n/a bytes += 8;
205n/a else
206n/a bytes += 4;
207n/a }
208n/a }
209n/a else
210n/a bytes += STACK_ARG_SIZE ((*ptr)->size);
211n/a }
212n/a
213n/a cif->bytes = bytes;
214n/a
215n/a return ffi_prep_cif_machdep (cif);
216n/a}
217n/a
218n/affi_status
219n/affi_prep_cif_machdep (ffi_cif * cif)
220n/a{
221n/a switch (cif->rtype->type)
222n/a {
223n/a case FFI_TYPE_VOID:
224n/a case FFI_TYPE_STRUCT:
225n/a case FFI_TYPE_FLOAT:
226n/a case FFI_TYPE_DOUBLE:
227n/a case FFI_TYPE_SINT64:
228n/a case FFI_TYPE_UINT64:
229n/a cif->flags = (unsigned) cif->rtype->type;
230n/a break;
231n/a
232n/a default:
233n/a cif->flags = FFI_TYPE_INT;
234n/a break;
235n/a }
236n/a
237n/a return FFI_OK;
238n/a}
239n/a
240n/aextern void ffi_call_SYSV (int (*)(char *, extended_cif *),
241n/a extended_cif *,
242n/a unsigned, unsigned, unsigned *, void (*fn) ())
243n/a __attribute__ ((__visibility__ ("hidden")));
244n/a
245n/avoid
246n/affi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
247n/a{
248n/a extended_cif ecif;
249n/a
250n/a ecif.cif = cif;
251n/a ecif.avalue = avalue;
252n/a
253n/a if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
254n/a {
255n/a ecif.rvalue = alloca (cif->rtype->size);
256n/a }
257n/a else
258n/a ecif.rvalue = rvalue;
259n/a
260n/a switch (cif->abi)
261n/a {
262n/a case FFI_SYSV:
263n/a ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
264n/a cif->flags, ecif.rvalue, fn);
265n/a break;
266n/a default:
267n/a FFI_ASSERT (0);
268n/a break;
269n/a }
270n/a}
271n/a
272n/a/* Because the following variables are not exported outside libffi, we
273n/a mark them hidden. */
274n/a
275n/a/* Assembly code for the jump stub. */
276n/aextern const char ffi_cris_trampoline_template[]
277n/a __attribute__ ((__visibility__ ("hidden")));
278n/a
279n/a/* Offset into ffi_cris_trampoline_template of where to put the
280n/a ffi_prep_closure_inner function. */
281n/aextern const int ffi_cris_trampoline_fn_offset
282n/a __attribute__ ((__visibility__ ("hidden")));
283n/a
284n/a/* Offset into ffi_cris_trampoline_template of where to put the
285n/a closure data. */
286n/aextern const int ffi_cris_trampoline_closure_offset
287n/a __attribute__ ((__visibility__ ("hidden")));
288n/a
289n/a/* This function is sibling-called (jumped to) by the closure
290n/a trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
291n/a PARAMS[4] to simplify handling of a straddling parameter. A copy
292n/a of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
293n/a put at the appropriate place in CLOSURE which is then executed and
294n/a the return value is passed back to the caller. */
295n/a
296n/astatic unsigned long long
297n/affi_prep_closure_inner (void **params, ffi_closure* closure)
298n/a{
299n/a char *register_args = (char *) params;
300n/a void *struct_ret = params[5];
301n/a char *stack_args = params[6];
302n/a char *ptr = register_args;
303n/a ffi_cif *cif = closure->cif;
304n/a ffi_type **arg_types = cif->arg_types;
305n/a
306n/a /* Max room needed is number of arguments as 64-bit values. */
307n/a void **avalue = alloca (closure->cif->nargs * sizeof(void *));
308n/a int i;
309n/a int doing_regs;
310n/a long long llret = 0;
311n/a
312n/a /* Find the address of each argument. */
313n/a for (i = 0, doing_regs = 1; i < cif->nargs; i++)
314n/a {
315n/a /* Types up to and including 8 bytes go by-value. */
316n/a if (arg_types[i]->size <= 4)
317n/a {
318n/a avalue[i] = ptr;
319n/a ptr += 4;
320n/a }
321n/a else if (arg_types[i]->size <= 8)
322n/a {
323n/a avalue[i] = ptr;
324n/a ptr += 8;
325n/a }
326n/a else
327n/a {
328n/a FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
329n/a
330n/a /* Passed by-reference, so copy the pointer. */
331n/a avalue[i] = *(void **) ptr;
332n/a ptr += 4;
333n/a }
334n/a
335n/a /* If we've handled more arguments than fit in registers, start
336n/a looking at the those passed on the stack. Step over the
337n/a first one if we had a straddling parameter. */
338n/a if (doing_regs && ptr >= register_args + 4*4)
339n/a {
340n/a ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
341n/a doing_regs = 0;
342n/a }
343n/a }
344n/a
345n/a /* Invoke the closure. */
346n/a (closure->fun) (cif,
347n/a
348n/a cif->rtype->type == FFI_TYPE_STRUCT
349n/a /* The caller allocated space for the return
350n/a structure, and passed a pointer to this space in
351n/a R9. */
352n/a ? struct_ret
353n/a
354n/a /* We take advantage of being able to ignore that
355n/a the high part isn't set if the return value is
356n/a not in R10:R11, but in R10 only. */
357n/a : (void *) &llret,
358n/a
359n/a avalue, closure->user_data);
360n/a
361n/a return llret;
362n/a}
363n/a
364n/a/* API function: Prepare the trampoline. */
365n/a
366n/affi_status
367n/affi_prep_closure_loc (ffi_closure* closure,
368n/a ffi_cif* cif,
369n/a void (*fun)(ffi_cif *, void *, void **, void*),
370n/a void *user_data,
371n/a void *codeloc)
372n/a{
373n/a void *innerfn = ffi_prep_closure_inner;
374n/a FFI_ASSERT (cif->abi == FFI_SYSV);
375n/a closure->cif = cif;
376n/a closure->user_data = user_data;
377n/a closure->fun = fun;
378n/a memcpy (closure->tramp, ffi_cris_trampoline_template,
379n/a FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
380n/a memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
381n/a &innerfn, sizeof (void *));
382n/a memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
383n/a &codeloc, sizeof (void *));
384n/a
385n/a return FFI_OK;
386n/a}