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

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

#countcontent
1n/a/*
2n/a * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
3n/a *
4n/a * Permission is hereby granted, free of charge, to any person obtaining
5n/a * a copy of this software and associated documentation files (the
6n/a * ``Software''), to deal in the Software without restriction, including
7n/a * without limitation the rights to use, copy, modify, merge, publish,
8n/a * distribute, sublicense, and/or sell copies of the Software, and to
9n/a * permit persons to whom the Software is furnished to do so, subject to
10n/a * the following conditions:
11n/a *
12n/a * The above copyright notice and this permission notice shall be included
13n/a * in all copies or substantial portions of the Software.
14n/a *
15n/a * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16n/a * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17n/a * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18n/a * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19n/a * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20n/a * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21n/a * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22n/a */
23n/a
24n/a/*
25n/a * vax Foreign Function Interface
26n/a *
27n/a * This file attempts to provide all the FFI entry points which can reliably
28n/a * be implemented in C.
29n/a */
30n/a
31n/a#include <ffi.h>
32n/a#include <ffi_common.h>
33n/a
34n/a#include <stdlib.h>
35n/a#include <unistd.h>
36n/a
37n/a#define CIF_FLAGS_CHAR 1 /* for struct only */
38n/a#define CIF_FLAGS_SHORT 2 /* for struct only */
39n/a#define CIF_FLAGS_INT 4
40n/a#define CIF_FLAGS_DINT 8
41n/a
42n/a/*
43n/a * Foreign Function Interface API
44n/a */
45n/a
46n/avoid ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *,
47n/a void (*) ());
48n/avoid *ffi_prep_args (extended_cif *ecif, void *stack);
49n/a
50n/avoid *
51n/affi_prep_args (extended_cif *ecif, void *stack)
52n/a{
53n/a unsigned int i;
54n/a void **p_argv;
55n/a char *argp;
56n/a ffi_type **p_arg;
57n/a void *struct_value_ptr;
58n/a
59n/a argp = stack;
60n/a
61n/a if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
62n/a && !ecif->cif->flags)
63n/a struct_value_ptr = ecif->rvalue;
64n/a else
65n/a struct_value_ptr = NULL;
66n/a
67n/a p_argv = ecif->avalue;
68n/a
69n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
70n/a i != 0;
71n/a i--, p_arg++)
72n/a {
73n/a size_t z;
74n/a
75n/a z = (*p_arg)->size;
76n/a if (z < sizeof (int))
77n/a {
78n/a switch ((*p_arg)->type)
79n/a {
80n/a case FFI_TYPE_SINT8:
81n/a *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
82n/a break;
83n/a
84n/a case FFI_TYPE_UINT8:
85n/a *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
86n/a break;
87n/a
88n/a case FFI_TYPE_SINT16:
89n/a *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
90n/a break;
91n/a
92n/a case FFI_TYPE_UINT16:
93n/a *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
94n/a break;
95n/a
96n/a case FFI_TYPE_STRUCT:
97n/a memcpy (argp, *p_argv, z);
98n/a break;
99n/a
100n/a default:
101n/a FFI_ASSERT (0);
102n/a }
103n/a z = sizeof (int);
104n/a }
105n/a else
106n/a {
107n/a memcpy (argp, *p_argv, z);
108n/a
109n/a /* Align if necessary. */
110n/a if ((sizeof(int) - 1) & z)
111n/a z = ALIGN(z, sizeof(int));
112n/a }
113n/a
114n/a p_argv++;
115n/a argp += z;
116n/a }
117n/a
118n/a return struct_value_ptr;
119n/a}
120n/a
121n/affi_status
122n/affi_prep_cif_machdep (ffi_cif *cif)
123n/a{
124n/a /* Set the return type flag */
125n/a switch (cif->rtype->type)
126n/a {
127n/a case FFI_TYPE_VOID:
128n/a cif->flags = 0;
129n/a break;
130n/a
131n/a case FFI_TYPE_STRUCT:
132n/a if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&
133n/a cif->rtype->elements[1])
134n/a {
135n/a cif->flags = 0;
136n/a break;
137n/a }
138n/a
139n/a if (cif->rtype->size == sizeof (char))
140n/a cif->flags = CIF_FLAGS_CHAR;
141n/a else if (cif->rtype->size == sizeof (short))
142n/a cif->flags = CIF_FLAGS_SHORT;
143n/a else if (cif->rtype->size == sizeof (int))
144n/a cif->flags = CIF_FLAGS_INT;
145n/a else if (cif->rtype->size == 2 * sizeof (int))
146n/a cif->flags = CIF_FLAGS_DINT;
147n/a else
148n/a cif->flags = 0;
149n/a break;
150n/a
151n/a default:
152n/a if (cif->rtype->size <= sizeof (int))
153n/a cif->flags = CIF_FLAGS_INT;
154n/a else
155n/a cif->flags = CIF_FLAGS_DINT;
156n/a break;
157n/a }
158n/a
159n/a return FFI_OK;
160n/a}
161n/a
162n/avoid
163n/affi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
164n/a{
165n/a extended_cif ecif;
166n/a
167n/a ecif.cif = cif;
168n/a ecif.avalue = avalue;
169n/a
170n/a /* If the return value is a struct and we don't have a return value
171n/a address then we need to make one. */
172n/a
173n/a if (rvalue == NULL
174n/a && cif->rtype->type == FFI_TYPE_STRUCT
175n/a && cif->flags == 0)
176n/a ecif.rvalue = alloca (cif->rtype->size);
177n/a else
178n/a ecif.rvalue = rvalue;
179n/a
180n/a switch (cif->abi)
181n/a {
182n/a case FFI_ELFBSD:
183n/a ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn);
184n/a break;
185n/a
186n/a default:
187n/a FFI_ASSERT (0);
188n/a break;
189n/a }
190n/a}
191n/a
192n/a/*
193n/a * Closure API
194n/a */
195n/a
196n/avoid ffi_closure_elfbsd (void);
197n/avoid ffi_closure_struct_elfbsd (void);
198n/aunsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *);
199n/a
200n/astatic void
201n/affi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp)
202n/a{
203n/a unsigned int i;
204n/a void **p_argv;
205n/a ffi_type **p_arg;
206n/a
207n/a p_argv = avalue;
208n/a
209n/a for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)
210n/a {
211n/a size_t z;
212n/a
213n/a z = (*p_arg)->size;
214n/a *p_argv = stackp;
215n/a
216n/a /* Align if necessary */
217n/a if ((sizeof (int) - 1) & z)
218n/a z = ALIGN(z, sizeof (int));
219n/a
220n/a p_argv++;
221n/a stackp += z;
222n/a }
223n/a}
224n/a
225n/aunsigned int
226n/affi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack)
227n/a{
228n/a ffi_cif *cif;
229n/a void **arg_area;
230n/a
231n/a cif = closure->cif;
232n/a arg_area = (void **) alloca (cif->nargs * sizeof (void *));
233n/a
234n/a ffi_prep_closure_elfbsd (cif, arg_area, stack);
235n/a
236n/a (closure->fun) (cif, resp, arg_area, closure->user_data);
237n/a
238n/a return cif->flags;
239n/a}
240n/a
241n/affi_status
242n/affi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
243n/a void (*fun)(ffi_cif *, void *, void **, void *),
244n/a void *user_data, void *codeloc)
245n/a{
246n/a char *tramp = (char *) codeloc;
247n/a void *fn;
248n/a
249n/a FFI_ASSERT (cif->abi == FFI_ELFBSD);
250n/a
251n/a /* entry mask */
252n/a *(unsigned short *)(tramp + 0) = 0x0000;
253n/a /* movl #closure, r0 */
254n/a tramp[2] = 0xd0;
255n/a tramp[3] = 0x8f;
256n/a *(unsigned int *)(tramp + 4) = (unsigned int) closure;
257n/a tramp[8] = 0x50;
258n/a
259n/a if (cif->rtype->type == FFI_TYPE_STRUCT
260n/a && !cif->flags)
261n/a fn = &ffi_closure_struct_elfbsd;
262n/a else
263n/a fn = &ffi_closure_elfbsd;
264n/a
265n/a /* jmpl #fn */
266n/a tramp[9] = 0x17;
267n/a tramp[10] = 0xef;
268n/a *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 -
269n/a (unsigned int)tramp - 9 - 6;
270n/a
271n/a closure->cif = cif;
272n/a closure->user_data = user_data;
273n/a closure->fun = fun;
274n/a
275n/a return FFI_OK;
276n/a}