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

Python code coverage for Modules/_ctypes/libffi/src/m88k/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 * m88k 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 * Only OpenBSD/m88k is currently supported; other platforms (such as
31n/a * Motorola's SysV/m88k) could be supported with the following tweaks:
32n/a *
33n/a * - non-OpenBSD systems use an `outgoing parameter area' as part of the
34n/a * 88BCS calling convention, which is not supported under OpenBSD from
35n/a * release 3.6 onwards. Supporting it should be as easy as taking it
36n/a * into account when adjusting the stack, in the assembly code.
37n/a *
38n/a * - the logic deciding whether a function argument gets passed through
39n/a * registers, or on the stack, has changed several times in OpenBSD in
40n/a * edge cases (especially for structs larger than 32 bytes being passed
41n/a * by value). The code below attemps to match the logic used by the
42n/a * system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend
43n/a * fixes.
44n/a */
45n/a
46n/a#include <ffi.h>
47n/a#include <ffi_common.h>
48n/a
49n/a#include <stdlib.h>
50n/a#include <unistd.h>
51n/a
52n/avoid ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *,
53n/a void (*fn) ());
54n/avoid *ffi_prep_args (void *, extended_cif *);
55n/avoid ffi_closure_OBSD (ffi_closure *);
56n/avoid ffi_closure_struct_OBSD (ffi_closure *);
57n/aunsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *,
58n/a char *);
59n/avoid ffi_cacheflush_OBSD (unsigned int, unsigned int);
60n/a
61n/a#define CIF_FLAGS_INT (1 << 0)
62n/a#define CIF_FLAGS_DINT (1 << 1)
63n/a
64n/a/*
65n/a * Foreign Function Interface API
66n/a */
67n/a
68n/a/* ffi_prep_args is called by the assembly routine once stack space has
69n/a been allocated for the function's arguments. */
70n/a
71n/avoid *
72n/affi_prep_args (void *stack, extended_cif *ecif)
73n/a{
74n/a unsigned int i;
75n/a void **p_argv;
76n/a char *argp, *stackp;
77n/a unsigned int *regp;
78n/a unsigned int regused;
79n/a ffi_type **p_arg;
80n/a void *struct_value_ptr;
81n/a
82n/a regp = (unsigned int *)stack;
83n/a stackp = (char *)(regp + 8);
84n/a regused = 0;
85n/a
86n/a if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
87n/a && !ecif->cif->flags)
88n/a struct_value_ptr = ecif->rvalue;
89n/a else
90n/a struct_value_ptr = NULL;
91n/a
92n/a p_argv = ecif->avalue;
93n/a
94n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++)
95n/a {
96n/a size_t z;
97n/a unsigned short t, a;
98n/a
99n/a z = (*p_arg)->size;
100n/a t = (*p_arg)->type;
101n/a a = (*p_arg)->alignment;
102n/a
103n/a /*
104n/a * Figure out whether the argument can be passed through registers
105n/a * or on the stack.
106n/a * The rule is that registers can only receive simple types not larger
107n/a * than 64 bits, or structs the exact size of a register and aligned to
108n/a * the size of a register.
109n/a */
110n/a if (t == FFI_TYPE_STRUCT)
111n/a {
112n/a if (z == sizeof (int) && a == sizeof (int) && regused < 8)
113n/a argp = (char *)regp;
114n/a else
115n/a argp = stackp;
116n/a }
117n/a else
118n/a {
119n/a if (z > sizeof (int) && regused < 8 - 1)
120n/a {
121n/a /* align to an even register pair */
122n/a if (regused & 1)
123n/a {
124n/a regp++;
125n/a regused++;
126n/a }
127n/a }
128n/a if (regused < 8)
129n/a argp = (char *)regp;
130n/a else
131n/a argp = stackp;
132n/a }
133n/a
134n/a /* Enforce proper stack alignment of 64-bit types */
135n/a if (argp == stackp && a > sizeof (int))
136n/a {
137n/a stackp = (char *) ALIGN(stackp, a);
138n/a argp = stackp;
139n/a }
140n/a
141n/a switch (t)
142n/a {
143n/a case FFI_TYPE_SINT8:
144n/a *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
145n/a break;
146n/a
147n/a case FFI_TYPE_UINT8:
148n/a *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
149n/a break;
150n/a
151n/a case FFI_TYPE_SINT16:
152n/a *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
153n/a break;
154n/a
155n/a case FFI_TYPE_UINT16:
156n/a *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
157n/a break;
158n/a
159n/a case FFI_TYPE_INT:
160n/a case FFI_TYPE_FLOAT:
161n/a case FFI_TYPE_UINT32:
162n/a case FFI_TYPE_SINT32:
163n/a case FFI_TYPE_POINTER:
164n/a *(unsigned int *) argp = *(unsigned int *) *p_argv;
165n/a break;
166n/a
167n/a case FFI_TYPE_DOUBLE:
168n/a case FFI_TYPE_UINT64:
169n/a case FFI_TYPE_SINT64:
170n/a case FFI_TYPE_STRUCT:
171n/a memcpy (argp, *p_argv, z);
172n/a break;
173n/a
174n/a default:
175n/a FFI_ASSERT (0);
176n/a }
177n/a
178n/a /* Align if necessary. */
179n/a if ((sizeof (int) - 1) & z)
180n/a z = ALIGN(z, sizeof (int));
181n/a
182n/a p_argv++;
183n/a
184n/a /* Be careful, once all registers are filled, and about to continue
185n/a on stack, regp == stackp. Therefore the check for regused as well. */
186n/a if (argp == (char *)regp && regused < 8)
187n/a {
188n/a regp += z / sizeof (int);
189n/a regused += z / sizeof (int);
190n/a }
191n/a else
192n/a stackp += z;
193n/a }
194n/a
195n/a return struct_value_ptr;
196n/a}
197n/a
198n/a/* Perform machine dependent cif processing */
199n/affi_status
200n/affi_prep_cif_machdep (ffi_cif *cif)
201n/a{
202n/a /* Set the return type flag */
203n/a switch (cif->rtype->type)
204n/a {
205n/a case FFI_TYPE_VOID:
206n/a cif->flags = 0;
207n/a break;
208n/a
209n/a case FFI_TYPE_STRUCT:
210n/a if (cif->rtype->size == sizeof (int) &&
211n/a cif->rtype->alignment == sizeof (int))
212n/a cif->flags = CIF_FLAGS_INT;
213n/a else
214n/a cif->flags = 0;
215n/a break;
216n/a
217n/a case FFI_TYPE_DOUBLE:
218n/a case FFI_TYPE_SINT64:
219n/a case FFI_TYPE_UINT64:
220n/a cif->flags = CIF_FLAGS_DINT;
221n/a break;
222n/a
223n/a default:
224n/a cif->flags = CIF_FLAGS_INT;
225n/a break;
226n/a }
227n/a
228n/a return FFI_OK;
229n/a}
230n/a
231n/avoid
232n/affi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
233n/a{
234n/a extended_cif ecif;
235n/a
236n/a ecif.cif = cif;
237n/a ecif.avalue = avalue;
238n/a
239n/a /* If the return value is a struct and we don't have a return value
240n/a address then we need to make one. */
241n/a
242n/a if (rvalue == NULL
243n/a && cif->rtype->type == FFI_TYPE_STRUCT
244n/a && (cif->rtype->size != sizeof (int)
245n/a || cif->rtype->alignment != sizeof (int)))
246n/a ecif.rvalue = alloca (cif->rtype->size);
247n/a else
248n/a ecif.rvalue = rvalue;
249n/a
250n/a switch (cif->abi)
251n/a {
252n/a case FFI_OBSD:
253n/a ffi_call_OBSD (cif->bytes, &ecif, cif->flags, ecif.rvalue, fn);
254n/a break;
255n/a
256n/a default:
257n/a FFI_ASSERT (0);
258n/a break;
259n/a }
260n/a}
261n/a
262n/a/*
263n/a * Closure API
264n/a */
265n/a
266n/astatic void
267n/affi_prep_closure_args_OBSD (ffi_cif *cif, void **avalue, unsigned int *regp,
268n/a char *stackp)
269n/a{
270n/a unsigned int i;
271n/a void **p_argv;
272n/a char *argp;
273n/a unsigned int regused;
274n/a ffi_type **p_arg;
275n/a
276n/a regused = 0;
277n/a
278n/a p_argv = avalue;
279n/a
280n/a for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)
281n/a {
282n/a size_t z;
283n/a unsigned short t, a;
284n/a
285n/a z = (*p_arg)->size;
286n/a t = (*p_arg)->type;
287n/a a = (*p_arg)->alignment;
288n/a
289n/a /*
290n/a * Figure out whether the argument has been passed through registers
291n/a * or on the stack.
292n/a * The rule is that registers can only receive simple types not larger
293n/a * than 64 bits, or structs the exact size of a register and aligned to
294n/a * the size of a register.
295n/a */
296n/a if (t == FFI_TYPE_STRUCT)
297n/a {
298n/a if (z == sizeof (int) && a == sizeof (int) && regused < 8)
299n/a argp = (char *)regp;
300n/a else
301n/a argp = stackp;
302n/a }
303n/a else
304n/a {
305n/a if (z > sizeof (int) && regused < 8 - 1)
306n/a {
307n/a /* align to an even register pair */
308n/a if (regused & 1)
309n/a {
310n/a regp++;
311n/a regused++;
312n/a }
313n/a }
314n/a if (regused < 8)
315n/a argp = (char *)regp;
316n/a else
317n/a argp = stackp;
318n/a }
319n/a
320n/a /* Enforce proper stack alignment of 64-bit types */
321n/a if (argp == stackp && a > sizeof (int))
322n/a {
323n/a stackp = (char *) ALIGN(stackp, a);
324n/a argp = stackp;
325n/a }
326n/a
327n/a if (z < sizeof (int) && t != FFI_TYPE_STRUCT)
328n/a *p_argv = (void *) (argp + sizeof (int) - z);
329n/a else
330n/a *p_argv = (void *) argp;
331n/a
332n/a /* Align if necessary */
333n/a if ((sizeof (int) - 1) & z)
334n/a z = ALIGN(z, sizeof (int));
335n/a
336n/a p_argv++;
337n/a
338n/a /* Be careful, once all registers are exhausted, and about to fetch from
339n/a stack, regp == stackp. Therefore the check for regused as well. */
340n/a if (argp == (char *)regp && regused < 8)
341n/a {
342n/a regp += z / sizeof (int);
343n/a regused += z / sizeof (int);
344n/a }
345n/a else
346n/a stackp += z;
347n/a }
348n/a}
349n/a
350n/aunsigned int
351n/affi_closure_OBSD_inner (ffi_closure *closure, void *resp, unsigned int *regp,
352n/a char *stackp)
353n/a{
354n/a ffi_cif *cif;
355n/a void **arg_area;
356n/a
357n/a cif = closure->cif;
358n/a arg_area = (void**) alloca (cif->nargs * sizeof (void *));
359n/a
360n/a ffi_prep_closure_args_OBSD(cif, arg_area, regp, stackp);
361n/a
362n/a (closure->fun) (cif, resp, arg_area, closure->user_data);
363n/a
364n/a return cif->flags;
365n/a}
366n/a
367n/affi_status
368n/affi_prep_closure_loc (ffi_closure* closure, ffi_cif* cif,
369n/a void (*fun)(ffi_cif*,void*,void**,void*),
370n/a void *user_data, void *codeloc)
371n/a{
372n/a unsigned int *tramp = (unsigned int *) codeloc;
373n/a void *fn;
374n/a
375n/a FFI_ASSERT (cif->abi == FFI_OBSD);
376n/a
377n/a if (cif->rtype->type == FFI_TYPE_STRUCT && !cif->flags)
378n/a fn = &ffi_closure_struct_OBSD;
379n/a else
380n/a fn = &ffi_closure_OBSD;
381n/a
382n/a /* or.u %r10, %r0, %hi16(fn) */
383n/a tramp[0] = 0x5d400000 | (((unsigned int)fn) >> 16);
384n/a /* or.u %r13, %r0, %hi16(closure) */
385n/a tramp[1] = 0x5da00000 | ((unsigned int)closure >> 16);
386n/a /* or %r10, %r10, %lo16(fn) */
387n/a tramp[2] = 0x594a0000 | (((unsigned int)fn) & 0xffff);
388n/a /* jmp.n %r10 */
389n/a tramp[3] = 0xf400c40a;
390n/a /* or %r13, %r13, %lo16(closure) */
391n/a tramp[4] = 0x59ad0000 | ((unsigned int)closure & 0xffff);
392n/a
393n/a ffi_cacheflush_OBSD((unsigned int)codeloc, FFI_TRAMPOLINE_SIZE);
394n/a
395n/a closure->cif = cif;
396n/a closure->user_data = user_data;
397n/a closure->fun = fun;
398n/a
399n/a return FFI_OK;
400n/a}