ยปCore Development>Code coverage>Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c

Python code coverage for Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c

#countcontent
1n/a#ifdef __i386__
2n/a/* -----------------------------------------------------------------------
3n/a ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
4n/a Copyright (c) 2002 Ranjit Mathew
5n/a Copyright (c) 2002 Bo Thorsen
6n/a Copyright (c) 2002 Roger Sayle
7n/a
8n/a x86 Foreign Function Interface
9n/a
10n/a Permission is hereby granted, free of charge, to any person obtaining
11n/a a copy of this software and associated documentation files (the
12n/a ``Software''), to deal in the Software without restriction, including
13n/a without limitation the rights to use, copy, modify, merge, publish,
14n/a distribute, sublicense, and/or sell copies of the Software, and to
15n/a permit persons to whom the Software is furnished to do so, subject to
16n/a the following conditions:
17n/a
18n/a The above copyright notice and this permission notice shall be included
19n/a in all copies or substantial portions of the Software.
20n/a
21n/a THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
22n/a OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24n/a IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25n/a OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26n/a ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27n/a OTHER DEALINGS IN THE SOFTWARE.
28n/a ----------------------------------------------------------------------- */
29n/a
30n/a#include <ffi.h>
31n/a#include <ffi_common.h>
32n/a
33n/a#include <stdlib.h>
34n/a
35n/a/* ffi_prep_args is called by the assembly routine once stack space
36n/a has been allocated for the function's arguments */
37n/a
38n/avoid ffi_prep_args(char *stack, extended_cif *ecif);
39n/a
40n/avoid ffi_prep_args(char *stack, extended_cif *ecif)
41n/a{
42n/a register unsigned int i;
43n/a register void **p_argv;
44n/a register char *argp;
45n/a register ffi_type **p_arg;
46n/a
47n/a argp = stack;
48n/a
49n/a if (ecif->cif->flags == FFI_TYPE_STRUCT)
50n/a {
51n/a *(void **) argp = ecif->rvalue;
52n/a argp += 4;
53n/a }
54n/a
55n/a p_argv = ecif->avalue;
56n/a
57n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
58n/a i != 0;
59n/a i--, p_arg++)
60n/a {
61n/a size_t z;
62n/a
63n/a /* Align if necessary */
64n/a if ((sizeof(int) - 1) & (unsigned) argp)
65n/a argp = (char *) ALIGN(argp, sizeof(int));
66n/a
67n/a z = (*p_arg)->size;
68n/a if (z < sizeof(int))
69n/a {
70n/a z = sizeof(int);
71n/a switch ((*p_arg)->type)
72n/a {
73n/a case FFI_TYPE_SINT8:
74n/a *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
75n/a break;
76n/a
77n/a case FFI_TYPE_UINT8:
78n/a *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
79n/a break;
80n/a
81n/a case FFI_TYPE_SINT16:
82n/a *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
83n/a break;
84n/a
85n/a case FFI_TYPE_UINT16:
86n/a *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
87n/a break;
88n/a
89n/a case FFI_TYPE_SINT32:
90n/a *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
91n/a break;
92n/a
93n/a case FFI_TYPE_UINT32:
94n/a *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
95n/a break;
96n/a
97n/a case FFI_TYPE_STRUCT:
98n/a *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
99n/a break;
100n/a
101n/a default:
102n/a FFI_ASSERT(0);
103n/a }
104n/a }
105n/a else
106n/a {
107n/a memcpy(argp, *p_argv, z);
108n/a }
109n/a p_argv++;
110n/a argp += z;
111n/a }
112n/a
113n/a return;
114n/a}
115n/a
116n/a/* Perform machine dependent cif processing */
117n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
118n/a{
119n/a /* Set the return type flag */
120n/a switch (cif->rtype->type)
121n/a {
122n/a case FFI_TYPE_VOID:
123n/a#ifdef X86
124n/a case FFI_TYPE_STRUCT:
125n/a case FFI_TYPE_UINT8:
126n/a case FFI_TYPE_UINT16:
127n/a case FFI_TYPE_SINT8:
128n/a case FFI_TYPE_SINT16:
129n/a#endif
130n/a
131n/a case FFI_TYPE_SINT64:
132n/a case FFI_TYPE_FLOAT:
133n/a case FFI_TYPE_DOUBLE:
134n/a case FFI_TYPE_LONGDOUBLE:
135n/a cif->flags = (unsigned) cif->rtype->type;
136n/a break;
137n/a
138n/a case FFI_TYPE_UINT64:
139n/a cif->flags = FFI_TYPE_SINT64;
140n/a break;
141n/a
142n/a#ifndef X86
143n/a case FFI_TYPE_STRUCT:
144n/a if (cif->rtype->size == 1)
145n/a {
146n/a cif->flags = FFI_TYPE_SINT8; /* same as char size */
147n/a }
148n/a else if (cif->rtype->size == 2)
149n/a {
150n/a cif->flags = FFI_TYPE_SINT16; /* same as short size */
151n/a }
152n/a else if (cif->rtype->size == 4)
153n/a {
154n/a cif->flags = FFI_TYPE_INT; /* same as int type */
155n/a }
156n/a else if (cif->rtype->size == 8)
157n/a {
158n/a cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
159n/a }
160n/a else
161n/a {
162n/a cif->flags = FFI_TYPE_STRUCT;
163n/a }
164n/a break;
165n/a#endif
166n/a
167n/a default:
168n/a cif->flags = FFI_TYPE_INT;
169n/a break;
170n/a }
171n/a
172n/a#ifdef X86_DARWIN
173n/a cif->bytes = (cif->bytes + 15) & ~0xF;
174n/a#endif
175n/a
176n/a return FFI_OK;
177n/a}
178n/a
179n/aextern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
180n/a unsigned, unsigned, unsigned *, void (*fn)());
181n/a
182n/a#ifdef X86_WIN32
183n/aextern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
184n/a unsigned, unsigned, unsigned *, void (*fn)());
185n/a
186n/a#endif /* X86_WIN32 */
187n/a
188n/avoid ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
189n/a{
190n/a extended_cif ecif;
191n/a
192n/a ecif.cif = cif;
193n/a ecif.avalue = avalue;
194n/a
195n/a /* If the return value is a struct and we don't have a return */
196n/a /* value address then we need to make one */
197n/a
198n/a if ((rvalue == NULL) &&
199n/a (cif->flags == FFI_TYPE_STRUCT))
200n/a {
201n/a ecif.rvalue = alloca(cif->rtype->size);
202n/a }
203n/a else
204n/a ecif.rvalue = rvalue;
205n/a
206n/a
207n/a switch (cif->abi)
208n/a {
209n/a case FFI_SYSV:
210n/a ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
211n/a fn);
212n/a break;
213n/a#ifdef X86_WIN32
214n/a case FFI_STDCALL:
215n/a ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
216n/a ecif.rvalue, fn);
217n/a break;
218n/a#endif /* X86_WIN32 */
219n/a default:
220n/a FFI_ASSERT(0);
221n/a break;
222n/a }
223n/a}
224n/a
225n/a
226n/a/** private members **/
227n/a
228n/astatic void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
229n/a void** args, ffi_cif* cif);
230n/avoid FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
231n/a__attribute__ ((regparm(1)));
232n/aunsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
233n/a__attribute__ ((regparm(1)));
234n/avoid FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
235n/a__attribute__ ((regparm(1)));
236n/a
237n/a/* This function is jumped to by the trampoline */
238n/a
239n/aunsigned int FFI_HIDDEN
240n/affi_closure_SYSV_inner (closure, respp, args)
241n/affi_closure *closure;
242n/avoid **respp;
243n/avoid *args;
244n/a{
245n/a // our various things...
246n/a ffi_cif *cif;
247n/a void **arg_area;
248n/a
249n/a cif = closure->cif;
250n/a arg_area = (void**) alloca (cif->nargs * sizeof (void*));
251n/a
252n/a /* this call will initialize ARG_AREA, such that each
253n/a * element in that array points to the corresponding
254n/a * value on the stack; and if the function returns
255n/a * a structure, it will re-set RESP to point to the
256n/a * structure return address. */
257n/a
258n/a ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
259n/a
260n/a (closure->fun) (cif, *respp, arg_area, closure->user_data);
261n/a
262n/a return cif->flags;
263n/a}
264n/a
265n/astatic void
266n/affi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
267n/a ffi_cif *cif)
268n/a{
269n/a register unsigned int i;
270n/a register void **p_argv;
271n/a register char *argp;
272n/a register ffi_type **p_arg;
273n/a
274n/a argp = stack;
275n/a
276n/a if ( cif->flags == FFI_TYPE_STRUCT ) {
277n/a *rvalue = *(void **) argp;
278n/a argp += 4;
279n/a }
280n/a
281n/a p_argv = avalue;
282n/a
283n/a for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
284n/a {
285n/a size_t z;
286n/a
287n/a /* Align if necessary */
288n/a if ((sizeof(int) - 1) & (unsigned) argp) {
289n/a argp = (char *) ALIGN(argp, sizeof(int));
290n/a }
291n/a
292n/a z = (*p_arg)->size;
293n/a
294n/a /* because we're little endian, this is what it turns into. */
295n/a
296n/a *p_argv = (void*) argp;
297n/a
298n/a p_argv++;
299n/a argp += z;
300n/a }
301n/a
302n/a return;
303n/a}
304n/a
305n/a/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
306n/a
307n/a#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
308n/a({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
309n/aunsigned int __fun = (unsigned int)(FUN); \
310n/aunsigned int __ctx = (unsigned int)(CTX); \
311n/aunsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
312n/a*(unsigned char*) &__tramp[0] = 0xb8; \
313n/a*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
314n/a*(unsigned char *) &__tramp[5] = 0xe9; \
315n/a*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
316n/a})
317n/a
318n/a
319n/a/* the cif must already be prep'ed */
320n/affi_status
321n/affi_prep_closure (ffi_closure* closure,
322n/a ffi_cif* cif,
323n/a void (*fun)(ffi_cif*,void*,void**,void*),
324n/a void *user_data)
325n/a{
326n/a if (cif->abi != FFI_SYSV)
327n/a return FFI_BAD_ABI;
328n/a
329n/a FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
330n/a &ffi_closure_SYSV, \
331n/a (void*)closure);
332n/a
333n/a closure->cif = cif;
334n/a closure->user_data = user_data;
335n/a closure->fun = fun;
336n/a
337n/a return FFI_OK;
338n/a}
339n/a
340n/a/* ------- Native raw API support -------------------------------- */
341n/a
342n/a#if !FFI_NO_RAW_API
343n/a
344n/affi_status
345n/affi_prep_raw_closure_loc (ffi_raw_closure* closure,
346n/a ffi_cif* cif,
347n/a void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
348n/a void *user_data,
349n/a void *codeloc)
350n/a{
351n/a int i;
352n/a
353n/a FFI_ASSERT (cif->abi == FFI_SYSV);
354n/a
355n/a // we currently don't support certain kinds of arguments for raw
356n/a // closures. This should be implemented by a separate assembly language
357n/a // routine, since it would require argument processing, something we
358n/a // don't do now for performance.
359n/a
360n/a for (i = cif->nargs-1; i >= 0; i--)
361n/a {
362n/a FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
363n/a FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
364n/a }
365n/a
366n/a
367n/a FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
368n/a codeloc);
369n/a
370n/a closure->cif = cif;
371n/a closure->user_data = user_data;
372n/a closure->fun = fun;
373n/a
374n/a return FFI_OK;
375n/a}
376n/a
377n/astatic void
378n/affi_prep_args_raw(char *stack, extended_cif *ecif)
379n/a{
380n/a memcpy (stack, ecif->avalue, ecif->cif->bytes);
381n/a}
382n/a
383n/a/* we borrow this routine from libffi (it must be changed, though, to
384n/a * actually call the function passed in the first argument. as of
385n/a * libffi-1.20, this is not the case.)
386n/a */
387n/a
388n/aextern void
389n/affi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
390n/a unsigned, unsigned *, void (*fn)());
391n/a
392n/a#ifdef X86_WIN32
393n/aextern void
394n/affi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
395n/a unsigned, unsigned *, void (*fn)());
396n/a#endif /* X86_WIN32 */
397n/a
398n/avoid
399n/affi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
400n/a{
401n/a extended_cif ecif;
402n/a void **avalue = (void **)fake_avalue;
403n/a
404n/a ecif.cif = cif;
405n/a ecif.avalue = avalue;
406n/a
407n/a /* If the return value is a struct and we don't have a return */
408n/a /* value address then we need to make one */
409n/a
410n/a if ((rvalue == NULL) &&
411n/a (cif->rtype->type == FFI_TYPE_STRUCT))
412n/a {
413n/a ecif.rvalue = alloca(cif->rtype->size);
414n/a }
415n/a else
416n/a ecif.rvalue = rvalue;
417n/a
418n/a
419n/a switch (cif->abi)
420n/a {
421n/a case FFI_SYSV:
422n/a ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
423n/a ecif.rvalue, fn);
424n/a break;
425n/a#ifdef X86_WIN32
426n/a case FFI_STDCALL:
427n/a ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
428n/a ecif.rvalue, fn);
429n/a break;
430n/a#endif /* X86_WIN32 */
431n/a default:
432n/a FFI_ASSERT(0);
433n/a break;
434n/a }
435n/a}
436n/a
437n/a#endif
438n/a#endif // __i386__