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

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

#countcontent
1n/a/* -----------------------------------------------------------------------
2n/a ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
3n/a Copyright (c) 2002 Ranjit Mathew
4n/a Copyright (c) 2002 Bo Thorsen
5n/a Copyright (c) 2002 Roger Sayle
6n/a Copyright (C) 2008, 2010 Free Software Foundation, Inc.
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,
22n/a EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23n/a MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24n/a NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25n/a HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26n/a WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27n/a OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28n/a DEALINGS IN THE SOFTWARE.
29n/a ----------------------------------------------------------------------- */
30n/a
31n/a#if !defined(__x86_64__) || defined(_WIN64)
32n/a
33n/a#ifdef _WIN64
34n/a#include <windows.h>
35n/a#endif
36n/a
37n/a#include <ffi.h>
38n/a#include <ffi_common.h>
39n/a
40n/a#include <stdlib.h>
41n/a
42n/a
43n/a/* ffi_prep_args is called by the assembly routine once stack space
44n/a has been allocated for the function's arguments */
45n/a
46n/avoid ffi_prep_args(char *stack, extended_cif *ecif);
47n/avoid ffi_prep_args(char *stack, extended_cif *ecif)
48n/a{
49n/a register unsigned int i;
50n/a register void **p_argv;
51n/a register char *argp;
52n/a register ffi_type **p_arg;
53n/a#ifndef X86_WIN64
54n/a size_t p_stack_args[2];
55n/a void *p_stack_data[2];
56n/a char *argp2 = stack;
57n/a int stack_args_count = 0;
58n/a int cabi = ecif->cif->abi;
59n/a#endif
60n/a
61n/a argp = stack;
62n/a
63n/a if ((ecif->cif->flags == FFI_TYPE_STRUCT
64n/a || ecif->cif->flags == FFI_TYPE_MS_STRUCT)
65n/a#ifdef X86_WIN64
66n/a && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
67n/a && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
68n/a#endif
69n/a )
70n/a {
71n/a *(void **) argp = ecif->rvalue;
72n/a#ifndef X86_WIN64
73n/a /* For fastcall/thiscall this is first register-passed
74n/a argument. */
75n/a if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
76n/a {
77n/a p_stack_args[stack_args_count] = sizeof (void*);
78n/a p_stack_data[stack_args_count] = argp;
79n/a ++stack_args_count;
80n/a }
81n/a#endif
82n/a argp += sizeof(void*);
83n/a }
84n/a
85n/a p_argv = ecif->avalue;
86n/a
87n/a for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
88n/a i != 0;
89n/a i--, p_arg++)
90n/a {
91n/a size_t z;
92n/a
93n/a /* Align if necessary */
94n/a if ((sizeof(void*) - 1) & (size_t) argp)
95n/a argp = (char *) ALIGN(argp, sizeof(void*));
96n/a
97n/a z = (*p_arg)->size;
98n/a#ifdef X86_WIN64
99n/a if (z > sizeof(ffi_arg)
100n/a || ((*p_arg)->type == FFI_TYPE_STRUCT
101n/a && (z != 1 && z != 2 && z != 4 && z != 8))
102n/a#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
103n/a || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
104n/a#endif
105n/a )
106n/a {
107n/a z = sizeof(ffi_arg);
108n/a *(void **)argp = *p_argv;
109n/a }
110n/a else if ((*p_arg)->type == FFI_TYPE_FLOAT)
111n/a {
112n/a memcpy(argp, *p_argv, z);
113n/a }
114n/a else
115n/a#endif
116n/a if (z < sizeof(ffi_arg))
117n/a {
118n/a z = sizeof(ffi_arg);
119n/a switch ((*p_arg)->type)
120n/a {
121n/a case FFI_TYPE_SINT8:
122n/a *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
123n/a break;
124n/a
125n/a case FFI_TYPE_UINT8:
126n/a *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
127n/a break;
128n/a
129n/a case FFI_TYPE_SINT16:
130n/a *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
131n/a break;
132n/a
133n/a case FFI_TYPE_UINT16:
134n/a *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
135n/a break;
136n/a
137n/a case FFI_TYPE_SINT32:
138n/a *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
139n/a break;
140n/a
141n/a case FFI_TYPE_UINT32:
142n/a *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
143n/a break;
144n/a
145n/a case FFI_TYPE_STRUCT:
146n/a *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
147n/a break;
148n/a
149n/a default:
150n/a FFI_ASSERT(0);
151n/a }
152n/a }
153n/a else
154n/a {
155n/a memcpy(argp, *p_argv, z);
156n/a }
157n/a
158n/a#ifndef X86_WIN64
159n/a /* For thiscall/fastcall convention register-passed arguments
160n/a are the first two none-floating-point arguments with a size
161n/a smaller or equal to sizeof (void*). */
162n/a if ((cabi == FFI_THISCALL && stack_args_count < 1)
163n/a || (cabi == FFI_FASTCALL && stack_args_count < 2))
164n/a {
165n/a if (z <= 4
166n/a && ((*p_arg)->type != FFI_TYPE_FLOAT
167n/a && (*p_arg)->type != FFI_TYPE_STRUCT))
168n/a {
169n/a p_stack_args[stack_args_count] = z;
170n/a p_stack_data[stack_args_count] = argp;
171n/a ++stack_args_count;
172n/a }
173n/a }
174n/a#endif
175n/a p_argv++;
176n/a#ifdef X86_WIN64
177n/a argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
178n/a#else
179n/a argp += z;
180n/a#endif
181n/a }
182n/a
183n/a#ifndef X86_WIN64
184n/a /* We need to move the register-passed arguments for thiscall/fastcall
185n/a on top of stack, so that those can be moved to registers ecx/edx by
186n/a call-handler. */
187n/a if (stack_args_count > 0)
188n/a {
189n/a size_t zz = (p_stack_args[0] + 3) & ~3;
190n/a char *h;
191n/a
192n/a /* Move first argument to top-stack position. */
193n/a if (p_stack_data[0] != argp2)
194n/a {
195n/a h = alloca (zz + 1);
196n/a memcpy (h, p_stack_data[0], zz);
197n/a memmove (argp2 + zz, argp2,
198n/a (size_t) ((char *) p_stack_data[0] - (char*)argp2));
199n/a memcpy (argp2, h, zz);
200n/a }
201n/a
202n/a argp2 += zz;
203n/a --stack_args_count;
204n/a if (zz > 4)
205n/a stack_args_count = 0;
206n/a
207n/a /* If we have a second argument, then move it on top
208n/a after the first one. */
209n/a if (stack_args_count > 0 && p_stack_data[1] != argp2)
210n/a {
211n/a zz = p_stack_args[1];
212n/a zz = (zz + 3) & ~3;
213n/a h = alloca (zz + 1);
214n/a h = alloca (zz + 1);
215n/a memcpy (h, p_stack_data[1], zz);
216n/a memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2));
217n/a memcpy (argp2, h, zz);
218n/a }
219n/a }
220n/a#endif
221n/a return;
222n/a}
223n/a
224n/a/* Perform machine dependent cif processing */
225n/affi_status ffi_prep_cif_machdep(ffi_cif *cif)
226n/a{
227n/a unsigned int i;
228n/a ffi_type **ptr;
229n/a
230n/a /* Set the return type flag */
231n/a switch (cif->rtype->type)
232n/a {
233n/a case FFI_TYPE_VOID:
234n/a case FFI_TYPE_UINT8:
235n/a case FFI_TYPE_UINT16:
236n/a case FFI_TYPE_SINT8:
237n/a case FFI_TYPE_SINT16:
238n/a#ifdef X86_WIN64
239n/a case FFI_TYPE_UINT32:
240n/a case FFI_TYPE_SINT32:
241n/a#endif
242n/a case FFI_TYPE_SINT64:
243n/a case FFI_TYPE_FLOAT:
244n/a case FFI_TYPE_DOUBLE:
245n/a#ifndef X86_WIN64
246n/a#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
247n/a case FFI_TYPE_LONGDOUBLE:
248n/a#endif
249n/a#endif
250n/a cif->flags = (unsigned) cif->rtype->type;
251n/a break;
252n/a
253n/a case FFI_TYPE_UINT64:
254n/a#ifdef X86_WIN64
255n/a case FFI_TYPE_POINTER:
256n/a#endif
257n/a cif->flags = FFI_TYPE_SINT64;
258n/a break;
259n/a
260n/a case FFI_TYPE_STRUCT:
261n/a#ifndef X86
262n/a if (cif->rtype->size == 1)
263n/a {
264n/a cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
265n/a }
266n/a else if (cif->rtype->size == 2)
267n/a {
268n/a cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
269n/a }
270n/a else if (cif->rtype->size == 4)
271n/a {
272n/a#ifdef X86_WIN64
273n/a cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
274n/a#else
275n/a cif->flags = FFI_TYPE_INT; /* same as int type */
276n/a#endif
277n/a }
278n/a else if (cif->rtype->size == 8)
279n/a {
280n/a cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
281n/a }
282n/a else
283n/a#endif
284n/a {
285n/a#ifdef X86_WIN32
286n/a if (cif->abi == FFI_MS_CDECL)
287n/a cif->flags = FFI_TYPE_MS_STRUCT;
288n/a else
289n/a#endif
290n/a cif->flags = FFI_TYPE_STRUCT;
291n/a /* allocate space for return value pointer */
292n/a cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
293n/a }
294n/a break;
295n/a
296n/a default:
297n/a#ifdef X86_WIN64
298n/a cif->flags = FFI_TYPE_SINT64;
299n/a break;
300n/a case FFI_TYPE_INT:
301n/a cif->flags = FFI_TYPE_SINT32;
302n/a#else
303n/a cif->flags = FFI_TYPE_INT;
304n/a#endif
305n/a break;
306n/a }
307n/a
308n/a for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
309n/a {
310n/a if (((*ptr)->alignment - 1) & cif->bytes)
311n/a cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
312n/a cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
313n/a }
314n/a
315n/a#ifdef X86_WIN64
316n/a /* ensure space for storing four registers */
317n/a cif->bytes += 4 * sizeof(ffi_arg);
318n/a#endif
319n/a
320n/a#ifndef X86_WIN32
321n/a#ifndef X86_WIN64
322n/a if (cif->abi != FFI_STDCALL && cif->abi != FFI_THISCALL && cif->abi != FFI_FASTCALL)
323n/a#endif
324n/a cif->bytes = (cif->bytes + 15) & ~0xF;
325n/a#endif
326n/a
327n/a return FFI_OK;
328n/a}
329n/a
330n/a#ifdef X86_WIN64
331n/aextern int
332n/affi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
333n/a unsigned, unsigned, unsigned *, void (*fn)(void));
334n/a#elif defined(X86_WIN32)
335n/aextern void
336n/affi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
337n/a unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
338n/a#else
339n/aextern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
340n/a unsigned, unsigned, unsigned *, void (*fn)(void));
341n/a#endif
342n/a
343n/avoid ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
344n/a{
345n/a extended_cif ecif;
346n/a
347n/a ecif.cif = cif;
348n/a ecif.avalue = avalue;
349n/a
350n/a /* If the return value is a struct and we don't have a return */
351n/a /* value address then we need to make one */
352n/a
353n/a#ifdef X86_WIN64
354n/a if (rvalue == NULL
355n/a && cif->flags == FFI_TYPE_STRUCT
356n/a && cif->rtype->size != 1 && cif->rtype->size != 2
357n/a && cif->rtype->size != 4 && cif->rtype->size != 8)
358n/a {
359n/a ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
360n/a }
361n/a#else
362n/a if (rvalue == NULL
363n/a && (cif->flags == FFI_TYPE_STRUCT
364n/a || cif->flags == FFI_TYPE_MS_STRUCT))
365n/a {
366n/a ecif.rvalue = alloca(cif->rtype->size);
367n/a }
368n/a#endif
369n/a else
370n/a ecif.rvalue = rvalue;
371n/a
372n/a
373n/a switch (cif->abi)
374n/a {
375n/a#ifdef X86_WIN64
376n/a case FFI_WIN64:
377n/a ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
378n/a cif->flags, ecif.rvalue, fn);
379n/a break;
380n/a#elif defined(X86_WIN32)
381n/a case FFI_SYSV:
382n/a case FFI_MS_CDECL:
383n/a case FFI_STDCALL:
384n/a ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
385n/a ecif.rvalue, fn);
386n/a break;
387n/a case FFI_THISCALL:
388n/a case FFI_FASTCALL:
389n/a {
390n/a unsigned int abi = cif->abi;
391n/a unsigned int i, passed_regs = 0;
392n/a
393n/a if (cif->flags == FFI_TYPE_STRUCT)
394n/a ++passed_regs;
395n/a
396n/a for (i=0; i < cif->nargs && passed_regs < 2;i++)
397n/a {
398n/a size_t sz;
399n/a
400n/a if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
401n/a || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
402n/a continue;
403n/a sz = (cif->arg_types[i]->size + 3) & ~3;
404n/a if (sz == 0 || sz > 4)
405n/a continue;
406n/a ++passed_regs;
407n/a }
408n/a if (passed_regs < 2 && abi == FFI_FASTCALL)
409n/a abi = FFI_THISCALL;
410n/a if (passed_regs < 1 && abi == FFI_THISCALL)
411n/a abi = FFI_STDCALL;
412n/a ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
413n/a ecif.rvalue, fn);
414n/a }
415n/a break;
416n/a#else
417n/a case FFI_SYSV:
418n/a ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
419n/a fn);
420n/a break;
421n/a#endif
422n/a default:
423n/a FFI_ASSERT(0);
424n/a break;
425n/a }
426n/a}
427n/a
428n/a
429n/a/** private members **/
430n/a
431n/a/* The following __attribute__((regparm(1))) decorations will have no effect
432n/a on MSVC or SUNPRO_C -- standard conventions apply. */
433n/astatic void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
434n/a void** args, ffi_cif* cif);
435n/avoid FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
436n/a __attribute__ ((regparm(1)));
437n/aunsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
438n/a __attribute__ ((regparm(1)));
439n/avoid FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
440n/a __attribute__ ((regparm(1)));
441n/a#ifdef X86_WIN32
442n/avoid FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
443n/a __attribute__ ((regparm(1)));
444n/a#endif
445n/a#ifndef X86_WIN64
446n/avoid FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
447n/a __attribute__ ((regparm(1)));
448n/avoid FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
449n/a __attribute__ ((regparm(1)));
450n/avoid FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *)
451n/a __attribute__ ((regparm(1)));
452n/a#else
453n/avoid FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
454n/a#endif
455n/a
456n/a/* This function is jumped to by the trampoline */
457n/a
458n/a#ifdef X86_WIN64
459n/avoid * FFI_HIDDEN
460n/affi_closure_win64_inner (ffi_closure *closure, void *args) {
461n/a ffi_cif *cif;
462n/a void **arg_area;
463n/a void *result;
464n/a void *resp = &result;
465n/a
466n/a cif = closure->cif;
467n/a arg_area = (void**) alloca (cif->nargs * sizeof (void*));
468n/a
469n/a /* this call will initialize ARG_AREA, such that each
470n/a * element in that array points to the corresponding
471n/a * value on the stack; and if the function returns
472n/a * a structure, it will change RESP to point to the
473n/a * structure return address. */
474n/a
475n/a ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
476n/a
477n/a (closure->fun) (cif, resp, arg_area, closure->user_data);
478n/a
479n/a /* The result is returned in rax. This does the right thing for
480n/a result types except for floats; we have to 'mov xmm0, rax' in the
481n/a caller to correct this.
482n/a TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
483n/a */
484n/a return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
485n/a}
486n/a
487n/a#else
488n/aunsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
489n/affi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
490n/a{
491n/a /* our various things... */
492n/a ffi_cif *cif;
493n/a void **arg_area;
494n/a
495n/a cif = closure->cif;
496n/a arg_area = (void**) alloca (cif->nargs * sizeof (void*));
497n/a
498n/a /* this call will initialize ARG_AREA, such that each
499n/a * element in that array points to the corresponding
500n/a * value on the stack; and if the function returns
501n/a * a structure, it will change RESP to point to the
502n/a * structure return address. */
503n/a
504n/a ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
505n/a
506n/a (closure->fun) (cif, *respp, arg_area, closure->user_data);
507n/a
508n/a return cif->flags;
509n/a}
510n/a#endif /* !X86_WIN64 */
511n/a
512n/astatic void
513n/affi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
514n/a ffi_cif *cif)
515n/a{
516n/a register unsigned int i;
517n/a register void **p_argv;
518n/a register char *argp;
519n/a register ffi_type **p_arg;
520n/a
521n/a argp = stack;
522n/a
523n/a#ifdef X86_WIN64
524n/a if (cif->rtype->size > sizeof(ffi_arg)
525n/a || (cif->flags == FFI_TYPE_STRUCT
526n/a && (cif->rtype->size != 1 && cif->rtype->size != 2
527n/a && cif->rtype->size != 4 && cif->rtype->size != 8))) {
528n/a *rvalue = *(void **) argp;
529n/a argp += sizeof(void *);
530n/a }
531n/a#else
532n/a if ( cif->flags == FFI_TYPE_STRUCT
533n/a || cif->flags == FFI_TYPE_MS_STRUCT ) {
534n/a *rvalue = *(void **) argp;
535n/a argp += sizeof(void *);
536n/a }
537n/a#endif
538n/a
539n/a p_argv = avalue;
540n/a
541n/a for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
542n/a {
543n/a size_t z;
544n/a
545n/a /* Align if necessary */
546n/a if ((sizeof(void*) - 1) & (size_t) argp) {
547n/a argp = (char *) ALIGN(argp, sizeof(void*));
548n/a }
549n/a
550n/a#ifdef X86_WIN64
551n/a if ((*p_arg)->size > sizeof(ffi_arg)
552n/a || ((*p_arg)->type == FFI_TYPE_STRUCT
553n/a && ((*p_arg)->size != 1 && (*p_arg)->size != 2
554n/a && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
555n/a {
556n/a z = sizeof(void *);
557n/a *p_argv = *(void **)argp;
558n/a }
559n/a else
560n/a#endif
561n/a {
562n/a z = (*p_arg)->size;
563n/a
564n/a /* because we're little endian, this is what it turns into. */
565n/a
566n/a *p_argv = (void*) argp;
567n/a }
568n/a
569n/a p_argv++;
570n/a#ifdef X86_WIN64
571n/a argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
572n/a#else
573n/a argp += z;
574n/a#endif
575n/a }
576n/a
577n/a return;
578n/a}
579n/a
580n/a#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
581n/a{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
582n/a void* __fun = (void*)(FUN); \
583n/a void* __ctx = (void*)(CTX); \
584n/a *(unsigned char*) &__tramp[0] = 0x41; \
585n/a *(unsigned char*) &__tramp[1] = 0xbb; \
586n/a *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
587n/a *(unsigned char*) &__tramp[6] = 0x48; \
588n/a *(unsigned char*) &__tramp[7] = 0xb8; \
589n/a *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
590n/a *(unsigned char *) &__tramp[16] = 0x49; \
591n/a *(unsigned char *) &__tramp[17] = 0xba; \
592n/a *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
593n/a *(unsigned char *) &__tramp[26] = 0x41; \
594n/a *(unsigned char *) &__tramp[27] = 0xff; \
595n/a *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
596n/a }
597n/a
598n/a/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
599n/a
600n/a#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
601n/a{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
602n/a unsigned int __fun = (unsigned int)(FUN); \
603n/a unsigned int __ctx = (unsigned int)(CTX); \
604n/a unsigned int __dis = __fun - (__ctx + 10); \
605n/a *(unsigned char*) &__tramp[0] = 0xb8; \
606n/a *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
607n/a *(unsigned char *) &__tramp[5] = 0xe9; \
608n/a *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
609n/a }
610n/a
611n/a#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \
612n/a{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
613n/a unsigned int __fun = (unsigned int)(FUN); \
614n/a unsigned int __ctx = (unsigned int)(CTX); \
615n/a unsigned int __dis = __fun - (__ctx + 49); \
616n/a unsigned short __size = (unsigned short)(SIZE); \
617n/a *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
618n/a *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
619n/a *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
620n/a *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
621n/a *(unsigned char*) &__tramp[13] = 0xb8; \
622n/a *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
623n/a *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
624n/a *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
625n/a *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
626n/a *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
627n/a *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
628n/a *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
629n/a *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
630n/a *(unsigned char*) &__tramp[39] = 0xb8; \
631n/a *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
632n/a *(unsigned char *) &__tramp[44] = 0xe8; \
633n/a *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
634n/a *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
635n/a *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
636n/a }
637n/a
638n/a#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX) \
639n/a{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
640n/a unsigned int __fun = (unsigned int)(FUN); \
641n/a unsigned int __ctx = (unsigned int)(CTX); \
642n/a unsigned int __dis = __fun - (__ctx + 10); \
643n/a *(unsigned char*) &__tramp[0] = 0xb8; \
644n/a *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
645n/a *(unsigned char *) &__tramp[5] = 0xe8; \
646n/a *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
647n/a }
648n/a
649n/a/* the cif must already be prep'ed */
650n/a
651n/affi_status
652n/affi_prep_closure_loc (ffi_closure* closure,
653n/a ffi_cif* cif,
654n/a void (*fun)(ffi_cif*,void*,void**,void*),
655n/a void *user_data,
656n/a void *codeloc)
657n/a{
658n/a#ifdef X86_WIN64
659n/a#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
660n/a#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
661n/a if (cif->abi == FFI_WIN64)
662n/a {
663n/a int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
664n/a FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
665n/a &ffi_closure_win64,
666n/a codeloc, mask);
667n/a /* make sure we can execute here */
668n/a }
669n/a#else
670n/a if (cif->abi == FFI_SYSV)
671n/a {
672n/a FFI_INIT_TRAMPOLINE (&closure->tramp[0],
673n/a &ffi_closure_SYSV,
674n/a (void*)codeloc);
675n/a }
676n/a else if (cif->abi == FFI_FASTCALL)
677n/a {
678n/a FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
679n/a &ffi_closure_FASTCALL,
680n/a (void*)codeloc);
681n/a }
682n/a else if (cif->abi == FFI_THISCALL)
683n/a {
684n/a FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
685n/a &ffi_closure_THISCALL,
686n/a (void*)codeloc);
687n/a }
688n/a else if (cif->abi == FFI_STDCALL)
689n/a {
690n/a FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
691n/a &ffi_closure_STDCALL,
692n/a (void*)codeloc);
693n/a }
694n/a#ifdef X86_WIN32
695n/a else if (cif->abi == FFI_MS_CDECL)
696n/a {
697n/a FFI_INIT_TRAMPOLINE (&closure->tramp[0],
698n/a &ffi_closure_SYSV,
699n/a (void*)codeloc);
700n/a }
701n/a#endif /* X86_WIN32 */
702n/a#endif /* !X86_WIN64 */
703n/a else
704n/a {
705n/a return FFI_BAD_ABI;
706n/a }
707n/a
708n/a closure->cif = cif;
709n/a closure->user_data = user_data;
710n/a closure->fun = fun;
711n/a
712n/a return FFI_OK;
713n/a}
714n/a
715n/a/* ------- Native raw API support -------------------------------- */
716n/a
717n/a#if !FFI_NO_RAW_API
718n/a
719n/affi_status
720n/affi_prep_raw_closure_loc (ffi_raw_closure* closure,
721n/a ffi_cif* cif,
722n/a void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
723n/a void *user_data,
724n/a void *codeloc)
725n/a{
726n/a int i;
727n/a
728n/a if (cif->abi != FFI_SYSV
729n/a#ifdef X86_WIN32
730n/a && cif->abi != FFI_THISCALL
731n/a#endif
732n/a )
733n/a return FFI_BAD_ABI;
734n/a
735n/a /* we currently don't support certain kinds of arguments for raw
736n/a closures. This should be implemented by a separate assembly
737n/a language routine, since it would require argument processing,
738n/a something we don't do now for performance. */
739n/a
740n/a for (i = cif->nargs-1; i >= 0; i--)
741n/a {
742n/a FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
743n/a FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
744n/a }
745n/a
746n/a#ifdef X86_WIN32
747n/a if (cif->abi == FFI_SYSV)
748n/a {
749n/a#endif
750n/a FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
751n/a codeloc);
752n/a#ifdef X86_WIN32
753n/a }
754n/a else if (cif->abi == FFI_THISCALL)
755n/a {
756n/a FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes);
757n/a }
758n/a#endif
759n/a closure->cif = cif;
760n/a closure->user_data = user_data;
761n/a closure->fun = fun;
762n/a
763n/a return FFI_OK;
764n/a}
765n/a
766n/astatic void
767n/affi_prep_args_raw(char *stack, extended_cif *ecif)
768n/a{
769n/a memcpy (stack, ecif->avalue, ecif->cif->bytes);
770n/a}
771n/a
772n/a/* we borrow this routine from libffi (it must be changed, though, to
773n/a * actually call the function passed in the first argument. as of
774n/a * libffi-1.20, this is not the case.)
775n/a */
776n/a
777n/avoid
778n/affi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
779n/a{
780n/a extended_cif ecif;
781n/a void **avalue = (void **)fake_avalue;
782n/a
783n/a ecif.cif = cif;
784n/a ecif.avalue = avalue;
785n/a
786n/a /* If the return value is a struct and we don't have a return */
787n/a /* value address then we need to make one */
788n/a
789n/a#ifdef X86_WIN64
790n/a if (rvalue == NULL
791n/a && cif->flags == FFI_TYPE_STRUCT
792n/a && cif->rtype->size != 1 && cif->rtype->size != 2
793n/a && cif->rtype->size != 4 && cif->rtype->size != 8)
794n/a {
795n/a ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
796n/a }
797n/a#else
798n/a if (rvalue == NULL
799n/a && (cif->flags == FFI_TYPE_STRUCT
800n/a || cif->flags == FFI_TYPE_MS_STRUCT))
801n/a {
802n/a ecif.rvalue = alloca(cif->rtype->size);
803n/a }
804n/a#endif
805n/a else
806n/a ecif.rvalue = rvalue;
807n/a
808n/a
809n/a switch (cif->abi)
810n/a {
811n/a#ifdef X86_WIN64
812n/a case FFI_WIN64:
813n/a ffi_call_win64(ffi_prep_args_raw, &ecif, cif->bytes,
814n/a cif->flags, ecif.rvalue, fn);
815n/a break;
816n/a#elif defined(X86_WIN32)
817n/a case FFI_SYSV:
818n/a case FFI_MS_CDECL:
819n/a case FFI_STDCALL:
820n/a ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
821n/a ecif.rvalue, fn);
822n/a break;
823n/a case FFI_THISCALL:
824n/a case FFI_FASTCALL:
825n/a {
826n/a unsigned int abi = cif->abi;
827n/a unsigned int i, passed_regs = 0;
828n/a
829n/a if (cif->flags == FFI_TYPE_STRUCT)
830n/a ++passed_regs;
831n/a
832n/a for (i=0; i < cif->nargs && passed_regs < 2;i++)
833n/a {
834n/a size_t sz;
835n/a
836n/a if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
837n/a || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
838n/a continue;
839n/a sz = (cif->arg_types[i]->size + 3) & ~3;
840n/a if (sz == 0 || sz > 4)
841n/a continue;
842n/a ++passed_regs;
843n/a }
844n/a if (passed_regs < 2 && abi == FFI_FASTCALL)
845n/a abi = FFI_THISCALL;
846n/a if (passed_regs < 1 && abi == FFI_THISCALL)
847n/a abi = FFI_STDCALL;
848n/a ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
849n/a ecif.rvalue, fn);
850n/a }
851n/a break;
852n/a#else
853n/a case FFI_SYSV:
854n/a ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue,
855n/a fn);
856n/a break;
857n/a#endif
858n/a default:
859n/a FFI_ASSERT(0);
860n/a break;
861n/a }
862n/a}
863n/a
864n/a#endif
865n/a
866n/a#endif /* !__x86_64__ || X86_WIN64 */
867n/a