Merge pull request #85 from joshtriplett/stdcall
stdcall support on Linux
This commit is contained in:
34
ChangeLog
34
ChangeLog
@@ -1,3 +1,37 @@
|
|||||||
|
2014-03-16 Josh Triplett <josh@joshtriplett.org>
|
||||||
|
|
||||||
|
Add support for stdcall, thiscall, and fastcall on non-Windows x86-32.
|
||||||
|
|
||||||
|
Linux supports the stdcall calling convention, either via functions
|
||||||
|
explicitly declared with the stdcall attribute, or via code compiled
|
||||||
|
with -mrtd which effectively makes stdcall the default.
|
||||||
|
|
||||||
|
This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on
|
||||||
|
non-Windows x86-32 platforms, as non-default calling conventions.
|
||||||
|
|
||||||
|
* Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32.
|
||||||
|
* src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL
|
||||||
|
on non-Windows x86-32. Increase trampoline size to accomodate these
|
||||||
|
calling conventions, and unify some ifdeffery.
|
||||||
|
* src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and
|
||||||
|
FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery.
|
||||||
|
* src/x86/win32.S: Support compiling on non-Windows x86-32 platforms.
|
||||||
|
On those platforms, avoid redefining the SYSV symbols already provided
|
||||||
|
by src/x86/sysv.S.
|
||||||
|
* testsuite/libffi.call/closure_stdcall.c: Run on non-Windows.
|
||||||
|
#define __stdcall if needed.
|
||||||
|
* testsuite/libffi.call/closure_thiscall.c: Run on non-Windows.
|
||||||
|
#define __fastcall if needed.
|
||||||
|
* testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows.
|
||||||
|
* testsuite/libffi.call/fastthis2_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/fastthis3_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/many2_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/many_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/strlen2_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/strlen_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/struct1_win32.c: Ditto.
|
||||||
|
* testsuite/libffi.call/struct2_win32.c: Ditto.
|
||||||
|
|
||||||
2014-03-16 Josh Triplett <josh@joshtriplett.org>
|
2014-03-16 Josh Triplett <josh@joshtriplett.org>
|
||||||
|
|
||||||
* prep_cif.c: Remove unnecessary ifdef for X86_WIN32.
|
* prep_cif.c: Remove unnecessary ifdef for X86_WIN32.
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ if BFIN
|
|||||||
nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
|
nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S
|
||||||
endif
|
endif
|
||||||
if X86
|
if X86
|
||||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
|
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S src/x86/win32.S
|
||||||
endif
|
endif
|
||||||
if X86_FREEBSD
|
if X86_FREEBSD
|
||||||
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
|
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||||||
register void **p_argv;
|
register void **p_argv;
|
||||||
register char *argp;
|
register char *argp;
|
||||||
register ffi_type **p_arg;
|
register ffi_type **p_arg;
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
size_t p_stack_args[2];
|
size_t p_stack_args[2];
|
||||||
void *p_stack_data[2];
|
void *p_stack_data[2];
|
||||||
char *argp2 = stack;
|
char *argp2 = stack;
|
||||||
@@ -69,7 +69,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
*(void **) argp = ecif->rvalue;
|
*(void **) argp = ecif->rvalue;
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
/* For fastcall/thiscall this is first register-passed
|
/* For fastcall/thiscall this is first register-passed
|
||||||
argument. */
|
argument. */
|
||||||
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
|
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
|
||||||
@@ -155,7 +155,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||||||
memcpy(argp, *p_argv, z);
|
memcpy(argp, *p_argv, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
/* For thiscall/fastcall convention register-passed arguments
|
/* For thiscall/fastcall convention register-passed arguments
|
||||||
are the first two none-floating-point arguments with a size
|
are the first two none-floating-point arguments with a size
|
||||||
smaller or equal to sizeof (void*). */
|
smaller or equal to sizeof (void*). */
|
||||||
@@ -180,7 +180,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
/* We need to move the register-passed arguments for thiscall/fastcall
|
/* We need to move the register-passed arguments for thiscall/fastcall
|
||||||
on top of stack, so that those can be moved to registers ecx/edx by
|
on top of stack, so that those can be moved to registers ecx/edx by
|
||||||
call-handler. */
|
call-handler. */
|
||||||
@@ -318,6 +318,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef X86_WIN32
|
#ifndef X86_WIN32
|
||||||
|
if (cif->abi != FFI_STDCALL && cif->abi != FFI_THISCALL && cif->abi != FFI_FASTCALL)
|
||||||
cif->bytes = (cif->bytes + 15) & ~0xF;
|
cif->bytes = (cif->bytes + 15) & ~0xF;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -328,11 +329,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
extern int
|
extern int
|
||||||
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
|
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
|
||||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||||
#elif defined(X86_WIN32)
|
#else
|
||||||
extern void
|
extern void
|
||||||
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
|
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
|
||||||
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
|
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||||
#else
|
|
||||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||||
#endif
|
#endif
|
||||||
@@ -374,10 +374,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|||||||
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
|
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
|
||||||
cif->flags, ecif.rvalue, fn);
|
cif->flags, ecif.rvalue, fn);
|
||||||
break;
|
break;
|
||||||
#elif defined(X86_WIN32)
|
#else
|
||||||
|
#ifndef X86_WIN32
|
||||||
|
case FFI_SYSV:
|
||||||
|
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
|
||||||
|
fn);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
case FFI_SYSV:
|
case FFI_SYSV:
|
||||||
case FFI_STDCALL:
|
|
||||||
case FFI_MS_CDECL:
|
case FFI_MS_CDECL:
|
||||||
|
#endif
|
||||||
|
case FFI_STDCALL:
|
||||||
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
|
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||||
ecif.rvalue, fn);
|
ecif.rvalue, fn);
|
||||||
break;
|
break;
|
||||||
@@ -410,11 +417,6 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|||||||
ecif.rvalue, fn);
|
ecif.rvalue, fn);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
case FFI_SYSV:
|
|
||||||
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
|
|
||||||
fn);
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
FFI_ASSERT(0);
|
FFI_ASSERT(0);
|
||||||
@@ -435,15 +437,14 @@ unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
|
|||||||
__attribute__ ((regparm(1)));
|
__attribute__ ((regparm(1)));
|
||||||
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
|
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
|
||||||
__attribute__ ((regparm(1)));
|
__attribute__ ((regparm(1)));
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
|
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
|
||||||
__attribute__ ((regparm(1)));
|
__attribute__ ((regparm(1)));
|
||||||
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
|
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
|
||||||
__attribute__ ((regparm(1)));
|
__attribute__ ((regparm(1)));
|
||||||
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
|
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
|
||||||
__attribute__ ((regparm(1)));
|
__attribute__ ((regparm(1)));
|
||||||
#endif
|
#else
|
||||||
#ifdef X86_WIN64
|
|
||||||
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
|
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -670,7 +671,6 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|||||||
&ffi_closure_SYSV,
|
&ffi_closure_SYSV,
|
||||||
(void*)codeloc);
|
(void*)codeloc);
|
||||||
}
|
}
|
||||||
#ifdef X86_WIN32
|
|
||||||
else if (cif->abi == FFI_THISCALL)
|
else if (cif->abi == FFI_THISCALL)
|
||||||
{
|
{
|
||||||
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
|
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
|
||||||
@@ -684,6 +684,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|||||||
&ffi_closure_STDCALL,
|
&ffi_closure_STDCALL,
|
||||||
(void*)codeloc, cif->bytes);
|
(void*)codeloc, cif->bytes);
|
||||||
}
|
}
|
||||||
|
#ifdef X86_WIN32
|
||||||
else if (cif->abi == FFI_MS_CDECL)
|
else if (cif->abi == FFI_MS_CDECL)
|
||||||
{
|
{
|
||||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
|
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
|
||||||
@@ -717,12 +718,12 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (cif->abi != FFI_SYSV) {
|
if (cif->abi != FFI_SYSV
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
if (cif->abi != FFI_THISCALL)
|
&& cif->abi != FFI_THISCALL
|
||||||
#endif
|
#endif
|
||||||
|
)
|
||||||
return FFI_BAD_ABI;
|
return FFI_BAD_ABI;
|
||||||
}
|
|
||||||
|
|
||||||
/* we currently don't support certain kinds of arguments for raw
|
/* we currently don't support certain kinds of arguments for raw
|
||||||
closures. This should be implemented by a separate assembly
|
closures. This should be implemented by a separate assembly
|
||||||
@@ -735,13 +736,13 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
|||||||
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
|
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
if (cif->abi == FFI_SYSV)
|
if (cif->abi == FFI_SYSV)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
|
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
|
||||||
codeloc);
|
codeloc);
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN64
|
||||||
}
|
}
|
||||||
else if (cif->abi == FFI_THISCALL)
|
else if (cif->abi == FFI_THISCALL)
|
||||||
{
|
{
|
||||||
@@ -791,10 +792,17 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
|||||||
|
|
||||||
switch (cif->abi)
|
switch (cif->abi)
|
||||||
{
|
{
|
||||||
#ifdef X86_WIN32
|
#ifndef X86_WIN32
|
||||||
|
case FFI_SYSV:
|
||||||
|
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
|
||||||
|
ecif.rvalue, fn);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
case FFI_SYSV:
|
case FFI_SYSV:
|
||||||
case FFI_STDCALL:
|
|
||||||
case FFI_MS_CDECL:
|
case FFI_MS_CDECL:
|
||||||
|
#endif
|
||||||
|
#ifndef X86_WIN64
|
||||||
|
case FFI_STDCALL:
|
||||||
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
|
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
|
||||||
ecif.rvalue, fn);
|
ecif.rvalue, fn);
|
||||||
break;
|
break;
|
||||||
@@ -827,11 +835,6 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
|||||||
ecif.rvalue, fn);
|
ecif.rvalue, fn);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
case FFI_SYSV:
|
|
||||||
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
|
|
||||||
ecif.rvalue, fn);
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
FFI_ASSERT(0);
|
FFI_ASSERT(0);
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ typedef enum ffi_abi {
|
|||||||
/* ---- Intel x86 and AMD x86-64 - */
|
/* ---- Intel x86 and AMD x86-64 - */
|
||||||
FFI_SYSV,
|
FFI_SYSV,
|
||||||
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
|
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
|
||||||
|
FFI_THISCALL,
|
||||||
|
FFI_FASTCALL,
|
||||||
|
FFI_STDCALL,
|
||||||
FFI_LAST_ABI,
|
FFI_LAST_ABI,
|
||||||
#if defined(__i386__) || defined(__i386)
|
#if defined(__i386__) || defined(__i386)
|
||||||
FFI_DEFAULT_ABI = FFI_SYSV
|
FFI_DEFAULT_ABI = FFI_SYSV
|
||||||
@@ -119,22 +122,14 @@ typedef enum ffi_abi {
|
|||||||
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
|
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
|
||||||
#define FFI_TRAMPOLINE_SIZE 24
|
#define FFI_TRAMPOLINE_SIZE 24
|
||||||
#define FFI_NATIVE_RAW_API 0
|
#define FFI_NATIVE_RAW_API 0
|
||||||
#else
|
#elif defined(X86_WIN64)
|
||||||
#ifdef X86_WIN32
|
|
||||||
#define FFI_TRAMPOLINE_SIZE 52
|
|
||||||
#else
|
|
||||||
#ifdef X86_WIN64
|
|
||||||
#define FFI_TRAMPOLINE_SIZE 29
|
#define FFI_TRAMPOLINE_SIZE 29
|
||||||
#define FFI_NATIVE_RAW_API 0
|
#define FFI_NATIVE_RAW_API 0
|
||||||
#define FFI_NO_RAW_API 1
|
#define FFI_NO_RAW_API 1
|
||||||
#else
|
#else
|
||||||
#define FFI_TRAMPOLINE_SIZE 10
|
#define FFI_TRAMPOLINE_SIZE 52
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef X86_WIN64
|
|
||||||
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
|
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -473,15 +473,21 @@ END
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#if defined(X86_WIN32)
|
||||||
|
#define USCORE_SYMBOL(x) _##x
|
||||||
|
#else
|
||||||
|
#define USCORE_SYMBOL(x) x
|
||||||
|
#endif
|
||||||
.text
|
.text
|
||||||
|
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_call_win32
|
FFI_HIDDEN(ffi_call_win32)
|
||||||
#ifndef __OS2__
|
.globl USCORE_SYMBOL(ffi_call_win32)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_call_win32; .scl 2; .type 32; .endef
|
.def _ffi_call_win32; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_call_win32:
|
USCORE_SYMBOL(ffi_call_win32):
|
||||||
.LFB1:
|
.LFB1:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
.LCFI0:
|
.LCFI0:
|
||||||
@@ -644,11 +650,12 @@ _ffi_call_win32:
|
|||||||
ret
|
ret
|
||||||
.ffi_call_win32_end:
|
.ffi_call_win32_end:
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_closure_THISCALL
|
FFI_HIDDEN(ffi_closure_THISCALL)
|
||||||
#ifndef __OS2__
|
.globl USCORE_SYMBOL(ffi_closure_THISCALL)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_closure_THISCALL; .scl 2; .type 32; .endef
|
.def _ffi_closure_THISCALL; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_closure_THISCALL:
|
USCORE_SYMBOL(ffi_closure_THISCALL):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
subl $40, %esp
|
subl $40, %esp
|
||||||
@@ -660,11 +667,14 @@ _ffi_closure_THISCALL:
|
|||||||
|
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_closure_SYSV
|
FFI_HIDDEN(ffi_closure_SYSV)
|
||||||
#ifndef __OS2__
|
#if defined(X86_WIN32)
|
||||||
|
.globl USCORE_SYMBOL(ffi_closure_SYSV)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_closure_SYSV; .scl 2; .type 32; .endef
|
.def _ffi_closure_SYSV; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_closure_SYSV:
|
USCORE_SYMBOL(ffi_closure_SYSV):
|
||||||
|
#endif
|
||||||
.LFB3:
|
.LFB3:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
.LCFI4:
|
.LCFI4:
|
||||||
@@ -678,7 +688,7 @@ _ffi_closure_SYSV:
|
|||||||
movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
|
movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
|
||||||
leal -12(%ebp), %edx
|
leal -12(%ebp), %edx
|
||||||
movl %edx, (%esp) /* &resp */
|
movl %edx, (%esp) /* &resp */
|
||||||
call _ffi_closure_SYSV_inner
|
call USCORE_SYMBOL(ffi_closure_SYSV_inner)
|
||||||
movl -12(%ebp), %ecx
|
movl -12(%ebp), %ecx
|
||||||
|
|
||||||
0:
|
0:
|
||||||
@@ -789,11 +799,12 @@ _ffi_closure_SYSV:
|
|||||||
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
|
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
|
||||||
#define CIF_FLAGS_OFFSET 20
|
#define CIF_FLAGS_OFFSET 20
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_closure_raw_THISCALL
|
FFI_HIDDEN(ffi_closure_raw_THISCALL)
|
||||||
#ifndef __OS2__
|
.globl USCORE_SYMBOL(ffi_closure_raw_THISCALL)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef
|
.def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_closure_raw_THISCALL:
|
USCORE_SYMBOL(ffi_closure_raw_THISCALL):
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp, %ebp
|
movl %esp, %ebp
|
||||||
pushl %esi
|
pushl %esi
|
||||||
@@ -805,11 +816,13 @@ _ffi_closure_raw_THISCALL:
|
|||||||
jmp .stubraw
|
jmp .stubraw
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_closure_raw_SYSV
|
#if defined(X86_WIN32)
|
||||||
#ifndef __OS2__
|
.globl USCORE_SYMBOL(ffi_closure_raw_SYSV)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef
|
.def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_closure_raw_SYSV:
|
USCORE_SYMBOL(ffi_closure_raw_SYSV):
|
||||||
|
#endif /* defined(X86_WIN32) */
|
||||||
.LFB4:
|
.LFB4:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
.LCFI6:
|
.LCFI6:
|
||||||
@@ -925,11 +938,12 @@ _ffi_closure_raw_SYSV:
|
|||||||
|
|
||||||
# This assumes we are using gas.
|
# This assumes we are using gas.
|
||||||
.balign 16
|
.balign 16
|
||||||
.globl _ffi_closure_STDCALL
|
FFI_HIDDEN(ffi_closure_STDCALL)
|
||||||
#ifndef __OS2__
|
.globl USCORE_SYMBOL(ffi_closure_STDCALL)
|
||||||
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
|
.def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
|
||||||
#endif
|
#endif
|
||||||
_ffi_closure_STDCALL:
|
USCORE_SYMBOL(ffi_closure_STDCALL):
|
||||||
.LFB5:
|
.LFB5:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
.LCFI9:
|
.LCFI9:
|
||||||
@@ -942,7 +956,7 @@ _ffi_closure_STDCALL:
|
|||||||
movl %edx, 4(%esp) /* args */
|
movl %edx, 4(%esp) /* args */
|
||||||
leal -12(%ebp), %edx
|
leal -12(%ebp), %edx
|
||||||
movl %edx, (%esp) /* &resp */
|
movl %edx, (%esp) /* &resp */
|
||||||
call _ffi_closure_SYSV_inner
|
call USCORE_SYMBOL(ffi_closure_SYSV_inner)
|
||||||
movl -12(%ebp), %ecx
|
movl -12(%ebp), %ecx
|
||||||
0:
|
0:
|
||||||
call 1f
|
call 1f
|
||||||
@@ -1034,7 +1048,7 @@ _ffi_closure_STDCALL:
|
|||||||
.ffi_closure_STDCALL_end:
|
.ffi_closure_STDCALL_end:
|
||||||
.LFE5:
|
.LFE5:
|
||||||
|
|
||||||
#ifndef __OS2__
|
#if defined(X86_WIN32) && !defined(__OS2__)
|
||||||
.section .eh_frame,"w"
|
.section .eh_frame,"w"
|
||||||
#endif
|
#endif
|
||||||
.Lframe1:
|
.Lframe1:
|
||||||
@@ -1094,7 +1108,6 @@ _ffi_closure_STDCALL:
|
|||||||
.align 4
|
.align 4
|
||||||
.LEFDE1:
|
.LEFDE1:
|
||||||
|
|
||||||
|
|
||||||
.LSFDE3:
|
.LSFDE3:
|
||||||
.long .LEFDE3-.LASFDE3 /* FDE Length */
|
.long .LEFDE3-.LASFDE3 /* FDE Length */
|
||||||
.LASFDE3:
|
.LASFDE3:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: <twalljava@dev.java.net> */
|
Originator: <twalljava@dev.java.net> */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -23,6 +23,9 @@ closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#define __stdcall __attribute__((stdcall))
|
||||||
|
#endif
|
||||||
typedef int (__stdcall *closure_test_type0)(int, int, int, int);
|
typedef int (__stdcall *closure_test_type0)(int, int, int, int);
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: <ktietz@redhat.com> */
|
Originator: <ktietz@redhat.com> */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -23,6 +23,9 @@ closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#define __thiscall __attribute__((thiscall))
|
||||||
|
#endif
|
||||||
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
|
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
|
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
PR: none.
|
PR: none.
|
||||||
Originator: From the original ffitest.c */
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
|
/* { dg-do run { target i?86-*-* } } */
|
||||||
#include "ffitest.h"
|
#include "ffitest.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
Reference in New Issue
Block a user