From b1393750038b16217fc45c48fcfa820ff632aafd Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Thu, 4 Jun 2009 16:02:47 +0000 Subject: [PATCH] [multiple changes] 2008-02-26 Anthony Green Thomas Heller * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C comment. 2008-02-03 Timothy Wall * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return offset based on code pointer, not data pointer. 2008-01-31 Timothy Wall * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall closures. * src/x86/ffitarget.h: Increase size of trampoline for stdcall closures. * src/x86/win32.S: Add assembly for stdcall closure. * src/x86/ffi.c: Initialize stdcall closure trampoline. From-SVN: r148174 --- libffi/ChangeLog | 20 +++++++ libffi/src/x86/ffi.c | 50 ++++++++++++++--- libffi/src/x86/ffitarget.h | 4 ++ libffi/src/x86/win32.S | 112 ++++++------------------------------- 4 files changed, 82 insertions(+), 104 deletions(-) diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 0b26cf52966..1ebf513330c 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,23 @@ +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + 2009-06-04 Andrew Haley * include/ffi.h.in: Change void (*)() to void (*)(void). diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index 2bca56e5ccb..767effb8380 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 25dcc1b9239..8178d064821 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 a6c9c0da101..4a57804c1bb 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: -- 2.30.2