aboutsummaryrefslogtreecommitdiff
path: root/libffi/src
diff options
context:
space:
mode:
Diffstat (limited to 'libffi/src')
-rw-r--r--libffi/src/x86/ffi.c50
-rw-r--r--libffi/src/x86/ffitarget.h4
-rw-r--r--libffi/src/x86/win32.S112
3 files changed, 62 insertions, 104 deletions
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
index 2bca56e..767effb 100644
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle
@@ -236,6 +236,10 @@ unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
+#ifdef X86_WIN32
+void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
+ __attribute__ ((regparm(1)));
+#endif
/* This function is jumped to by the trampoline */
@@ -245,7 +249,7 @@ ffi_closure_SYSV_inner (closure, respp, args)
void **respp;
void *args;
{
- // our various things...
+ /* our various things... */
ffi_cif *cif;
void **arg_area;
@@ -311,13 +315,26 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
- unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
+ unsigned int __dis = __fun - (__ctx + 10); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe9; \
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
})
+#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - (__ctx + 10); \
+ unsigned short __size = (unsigned short)(SIZE); \
+ *(unsigned char*) &__tramp[0] = 0xb8; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+ *(unsigned char *) &__tramp[5] = 0xe8; \
+ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
+ *(unsigned char *) &__tramp[10] = 0xc2; \
+ *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
+ })
/* the cif must already be prep'ed */
@@ -328,11 +345,24 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *user_data,
void *codeloc)
{
- FFI_ASSERT (cif->abi == FFI_SYSV);
-
- FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
- &ffi_closure_SYSV, \
- codeloc);
+ if (cif->abi == FFI_SYSV)
+ {
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+ &ffi_closure_SYSV,
+ (void*)codeloc);
+ }
+#ifdef X86_WIN32
+ else if (cif->abi == FFI_STDCALL)
+ {
+ FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
+ &ffi_closure_STDCALL,
+ (void*)codeloc, cif->bytes);
+ }
+#endif
+ else
+ {
+ return FFI_BAD_ABI;
+ }
closure->cif = cif;
closure->user_data = user_data;
@@ -354,7 +384,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
{
int i;
- FFI_ASSERT (cif->abi == FFI_SYSV);
+ if (cif->abi != FFI_SYSV) {
+ return FFI_BAD_ABI;
+ }
// we currently don't support certain kinds of arguments for raw
// closures. This should be implemented by a separate assembly language
diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h
index 25dcc1b..8178d06 100644
--- a/libffi/src/x86/ffitarget.h
+++ b/libffi/src/x86/ffitarget.h
@@ -78,7 +78,11 @@ typedef enum ffi_abi {
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 13
+#else
#define FFI_TRAMPOLINE_SIZE 10
+#endif
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
index a6c9c0d..4a57804 100644
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -264,6 +264,22 @@ sc_epilogue:
.ffi_call_STDCALL_end:
.LFE2:
+ .globl _ffi_closure_STDCALL
+_ffi_closure_STDCALL:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $40, %esp
+ leal -24(%ebp), %edx
+ movl %edx, -12(%ebp) /* resp */
+ leal 12(%ebp), %edx /* account for stub return address on stack */
+ movl %edx, 4(%esp) /* args */
+ leal -12(%ebp), %edx
+ movl %edx, (%esp) /* &resp */
+ call _ffi_closure_SYSV_inner
+ movl -12(%ebp), %ecx
+ jmp .Lcls_return_result
+.ffi_closure_STDCALL_end:
+
# This assumes we are using gas.
.balign 16
.globl _ffi_closure_SYSV
@@ -283,6 +299,7 @@ _ffi_closure_SYSV:
movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx
+.Lcls_return_result:
cmpl $FFI_TYPE_INT, %eax
je .Lcls_retint
cmpl $FFI_TYPE_FLOAT, %eax
@@ -392,70 +409,6 @@ _ffi_closure_raw_SYSV:
#endif /* !FFI_NO_RAW_API */
- # This assumes we are using gas.
- .balign 16
- .globl _ffi_closure_STDCALL
- .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
-_ffi_closure_STDCALL:
-.LFB5:
- pushl %ebp
-.LCFI9:
- movl %esp, %ebp
-.LCFI10:
- subl $40, %esp
- leal -24(%ebp), %edx
- movl %edx, -12(%ebp) /* resp */
- leal 12(%ebp), %edx /* account for stub return address on stack */
- movl %edx, 4(%esp) /* args */
- leal -12(%ebp), %edx
- movl %edx, (%esp) /* &resp */
- call _ffi_closure_SYSV_inner
- movl -12(%ebp), %ecx
- /* It would be nice to just share this code with the
- duplicate sequence in _ffi_closure_SYSV, if only
- there were some way to represent that in the EH info. */
- cmpl $FFI_TYPE_INT, %eax
- je .Lscls_retint
- cmpl $FFI_TYPE_FLOAT, %eax
- je .Lscls_retfloat
- cmpl $FFI_TYPE_DOUBLE, %eax
- je .Lscls_retdouble
- cmpl $FFI_TYPE_LONGDOUBLE, %eax
- je .Lscls_retldouble
- cmpl $FFI_TYPE_SINT64, %eax
- je .Lscls_retllong
- cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */
- je .Lscls_retstruct1
- cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
- je .Lscls_retstruct2
-.Lscls_epilogue:
- movl %ebp, %esp
- popl %ebp
- ret
-.Lscls_retint:
- movl (%ecx), %eax
- jmp .Lscls_epilogue
-.Lscls_retfloat:
- flds (%ecx)
- jmp .Lscls_epilogue
-.Lscls_retdouble:
- fldl (%ecx)
- jmp .Lscls_epilogue
-.Lscls_retldouble:
- fldt (%ecx)
- jmp .Lscls_epilogue
-.Lscls_retllong:
- movl (%ecx), %eax
- movl 4(%ecx), %edx
- jmp .Lscls_epilogue
-.Lscls_retstruct1:
- movsbl (%ecx), %eax
- jmp .Lscls_epilogue
-.Lscls_retstruct2:
- movswl (%ecx), %eax
- jmp .Lscls_epilogue
-.ffi_closure_STDCALL_end:
-.LFE5:
.section .eh_frame,"w"
.Lframe1:
@@ -618,34 +571,3 @@ _ffi_closure_STDCALL:
.LEFDE4:
#endif /* !FFI_NO_RAW_API */
-
-.LSFDE5:
- .long .LEFDE5-.LASFDE5 /* FDE Length */
-.LASFDE5:
- .long .LASFDE5-.Lframe1 /* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
- .long .LFB5-. /* FDE initial location */
-#else
- .long .LFB5
-#endif
- .long .LFE5-.LFB5 /* FDE address range */
-#ifdef __PIC__
- .byte 0x0 /* .uleb128 0x0; Augmentation size */
-#endif
- /* DW_CFA_xxx CFI instructions go here. */
-
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .long .LCFI9-.LFB5
- .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
- .byte 0x8 /* .uleb128 0x8 */
- .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
- .byte 0x2 /* .uleb128 0x2 */
-
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .long .LCFI10-.LCFI9
- .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
- .byte 0x5 /* .uleb128 0x5 */
-
- /* End of DW_CFA_xxx CFI instructions. */
- .align 4
-.LEFDE5: