diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-11 21:18:24 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-11 21:18:24 +0000 |
commit | 33b4ca908dbd38df9fa8ccebb4c1b08d33a588f1 (patch) | |
tree | 26c42f7f1f69f7735ef39926c2c1dd7be903a44c /libffi | |
parent | 2e5251888527a5bbf222a02166432959eb42dc0e (diff) | |
download | gcc-33b4ca908dbd38df9fa8ccebb4c1b08d33a588f1.tar.gz |
* configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
(AH_BOTTOM): Add FFI_HIDDEN definition.
* configure: Rebuilt.
* fficonfig.h.in: Rebuilt.
* src/powerpc/ffi.c (hidden): Remove.
(ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64,
ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden.
* src/powerpc/linux64_closure.S (ffi_closure_LINUX64,
.ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden.
* src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove,
add FFI_HIDDEN to its prototype.
(ffi_closure_SYSV_inner): New.
* src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
* src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103002 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi')
-rw-r--r-- | libffi/ChangeLog | 17 | ||||
-rwxr-xr-x | libffi/configure | 34 | ||||
-rw-r--r-- | libffi/configure.ac | 32 | ||||
-rw-r--r-- | libffi/fficonfig.h.in | 19 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi.c | 24 | ||||
-rw-r--r-- | libffi/src/powerpc/linux64_closure.S | 3 | ||||
-rw-r--r-- | libffi/src/x86/ffi.c | 110 | ||||
-rw-r--r-- | libffi/src/x86/sysv.S | 196 | ||||
-rw-r--r-- | libffi/src/x86/win32.S | 114 |
9 files changed, 433 insertions, 116 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 536d6639f3f..33fe14ae332 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,20 @@ +2005-08-11 Jakub Jelinek <jakub@redhat.com> + + * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. + (AH_BOTTOM): Add FFI_HIDDEN definition. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * src/powerpc/ffi.c (hidden): Remove. + (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, + ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, + .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. + * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, + add FFI_HIDDEN to its prototype. + (ffi_closure_SYSV_inner): New. + * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + 2005-08-10 Alfred M. Szmidt <ams@gnu.org> PR libffi/21819: diff --git a/libffi/configure b/libffi/configure index 07ac781d298..a6a6e09d06c 100755 --- a/libffi/configure +++ b/libffi/configure @@ -7522,6 +7522,40 @@ _ACEOF fi +echo "$as_me:$LINENO: checking for __attribute__((visibility(\"hidden\")))" >&5 +echo $ECHO_N "checking for __attribute__((visibility(\"hidden\")))... $ECHO_C" >&6 +if test "${libffi_cv_hidden_visibility_attribute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* + +fi +echo "$as_me:$LINENO: result: $libffi_cv_hidden_visibility_attribute" >&5 +echo "${ECHO_T}$libffi_cv_hidden_visibility_attribute" >&6 +if test $libffi_cv_hidden_visibility_attribute = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1 +_ACEOF + +fi + + + + diff --git a/libffi/configure.ac b/libffi/configure.ac index 2bf13f6cde7..eac8e8fe42e 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -192,6 +192,38 @@ else [Define to the flags needed for the .section .eh_frame directive.]) fi +AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], + libffi_cv_hidden_visibility_attribute, [ + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* + ]) +if test $libffi_cv_hidden_visibility_attribute = yes; then + AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, + [Define if __attribute__((visibility("hidden"))) is supported.]) +fi + +AH_BOTTOM([ +#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) .hidden name +#else +#define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) +#endif +#else +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) +#else +#define FFI_HIDDEN +#endif +#endif +]) + AC_SUBST(TARGET) AC_SUBST(TARGETDIR) diff --git a/libffi/fficonfig.h.in b/libffi/fficonfig.h.in index e0cab345cc1..f982707344f 100644 --- a/libffi/fficonfig.h.in +++ b/libffi/fficonfig.h.in @@ -34,6 +34,9 @@ */ #undef HAVE_AS_SPARC_UA_PCREL +/* Define if __attribute__((visibility("hidden"))) is supported. */ +#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H @@ -133,3 +136,19 @@ /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN + + +#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) .hidden name +#else +#define FFI_HIDDEN __attribute__ ((visibility ("hidden"))) +#endif +#else +#ifdef LIBFFI_ASM +#define FFI_HIDDEN(name) +#else +#define FFI_HIDDEN +#endif +#endif + diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index b337aa74c11..ed02bf38d56 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -29,15 +29,9 @@ #include <stdlib.h> #include <stdio.h> -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 1) -# define hidden __attribute__ ((visibility ("hidden"))) -#else -# define hidden -#endif - extern void ffi_closure_SYSV(void); -extern void hidden ffi_closure_LINUX64(void); +extern void FFI_HIDDEN ffi_closure_LINUX64(void); enum { /* The assembly depends on these exact flags. */ @@ -301,7 +295,7 @@ enum { ASM_NEEDS_REGISTERS64 = 4 }; */ /*@-exportheader@*/ -void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) +void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) /*@=exportheader@*/ { const unsigned long bytes = ecif->cif->bytes; @@ -697,10 +691,10 @@ extern void ffi_call_SYSV(/*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, void (*fn)()); -extern void hidden ffi_call_LINUX64(/*@out@*/ extended_cif *, - unsigned long, unsigned long, - /*@out@*/ unsigned long *, - void (*fn)()); +extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *, + unsigned long, unsigned long, + /*@out@*/ unsigned long *, + void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ @@ -1020,10 +1014,10 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, } -int hidden ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*, - ffi_dblfl*); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*, + ffi_dblfl*); -int hidden +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, unsigned long *pst, ffi_dblfl *pfr) { diff --git a/libffi/src/powerpc/linux64_closure.S b/libffi/src/powerpc/linux64_closure.S index 5764971fbe1..b19bc718b50 100644 --- a/libffi/src/powerpc/linux64_closure.S +++ b/libffi/src/powerpc/linux64_closure.S @@ -5,7 +5,8 @@ .file "linux64_closure.S" #ifdef __powerpc64__ - .hidden ffi_closure_LINUX64, .ffi_closure_LINUX64 + FFI_HIDDEN (ffi_closure_LINUX64) + FFI_HIDDEN (.ffi_closure_LINUX64) .globl ffi_closure_LINUX64, .ffi_closure_LINUX64 .section ".opd","aw" .align 3 diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index 633e549c997..e4d5fc31c8a 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -241,26 +241,24 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif, static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); -static void ffi_closure_SYSV (ffi_closure *) +void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) __attribute__ ((regparm(1))); -static void ffi_closure_raw_SYSV (ffi_raw_closure *) +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))); /* This function is jumped to by the trampoline */ -static void -ffi_closure_SYSV (closure) +unsigned int FFI_HIDDEN +ffi_closure_SYSV_inner (closure, respp, args) ffi_closure *closure; + void **respp; + void *args; { - // this is our return value storage - long double res; - // our various things... ffi_cif *cif; void **arg_area; - unsigned short rtype; - void *resp = (void*)&res; - void *args = __builtin_dwarf_cfa (); cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); @@ -271,46 +269,11 @@ ffi_closure_SYSV (closure) * a structure, it will re-set RESP to point to the * structure return address. */ - ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); - rtype = cif->flags; + (closure->fun) (cif, *respp, arg_area, closure->user_data); - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax;" - "movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -#ifdef X86_WIN32 - else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct */ - { - asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_SINT16) /* 2-bytes struct */ - { - asm ("movswl (%0),%%eax" : : "r" (resp) : "eax"); - } -#endif + return cif->flags; } /*@-exportheader@*/ @@ -394,57 +357,6 @@ ffi_prep_closure (ffi_closure* closure, #if !FFI_NO_RAW_API -static void -ffi_closure_raw_SYSV (closure) - ffi_raw_closure *closure; -{ - // this is our return value storage - long double res; - - // our various things... - ffi_raw *raw_args; - ffi_cif *cif; - unsigned short rtype; - void *resp = (void*)&res; - - /* get the cif */ - cif = closure->cif; - - /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */ - raw_args = (ffi_raw*) __builtin_dwarf_cfa (); - - (closure->fun) (cif, resp, raw_args, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -} - - - - ffi_status ffi_prep_raw_closure (ffi_raw_closure* closure, ffi_cif* cif, diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S index 53a4c2b7e98..46759f43498 100644 --- a/libffi/src/x86/sysv.S +++ b/libffi/src/x86/sysv.S @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc. + sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. X86 Foreign Function Interface @@ -130,6 +130,135 @@ epilogue: .ffi_call_SYSV_end: .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV + .align 4 +FFI_HIDDEN (ffi_closure_SYSV) +.globl ffi_closure_SYSV + .type ffi_closure_SYSV, @function + +ffi_closure_SYSV: +.LFB2: + pushl %ebp +.LCFI2: + movl %esp, %ebp +.LCFI3: + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ +#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__ + call ffi_closure_SYSV_inner +#else + movl %ebx, 8(%esp) +.LCFI7: + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx +#endif + movl -12(%ebp), %ecx + cmpl $FFI_TYPE_INT, %eax + je .Lcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lcls_retllong +.Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue +.Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue +.Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue +.Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue +.Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue +.LFE2: + .size ffi_closure_SYSV, .-ffi_closure_SYSV + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + + .align 4 +FFI_HIDDEN (ffi_closure_raw_SYSV) +.globl ffi_closure_raw_SYSV + .type ffi_closure_raw_SYSV, @function + +ffi_closure_raw_SYSV: +.LFB3: + pushl %ebp +.LCFI4: + movl %esp, %ebp +.LCFI5: + pushl %esi +.LCFI6: + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ + cmpl $FFI_TYPE_INT, %eax + je .Lrcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lrcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lrcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lrcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lrcls_retllong +.Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret +.Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue +.Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue +.LFE3: + .size ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV +#endif + .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */ @@ -180,5 +309,70 @@ epilogue: .byte 0x5 /* .uleb128 0x5 */ .align 4 .LEFDE1: +.LSFDE2: + .long .LEFDE2-.LASFDE2 /* FDE Length */ +.LASFDE2: + .long .LASFDE2-.Lframe1 /* FDE CIE offset */ +#ifdef __PIC__ + .long .LFB2-. /* FDE initial location */ +#else + .long .LFB2 +#endif + .long .LFE2-.LFB2 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI2-.LFB2 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ + .byte 0x2 /* .uleb128 0x2 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI3-.LCFI2 + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0x5 /* .uleb128 0x5 */ +#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI7-.LCFI3 + .byte 0x83 /* DW_CFA_offset, column 0x3 */ + .byte 0xa /* .uleb128 0xa */ +#endif + .align 4 +.LEFDE2: + +#if !FFI_NO_RAW_API + +.LSFDE3: + .long .LEFDE3-.LASFDE3 /* FDE Length */ +.LASFDE3: + .long .LASFDE3-.Lframe1 /* FDE CIE offset */ +#ifdef __PIC__ + .long .LFB3-. /* FDE initial location */ +#else + .long .LFB3 +#endif + .long .LFE3-.LFB3 /* FDE address range */ +#ifdef __PIC__ + .byte 0x0 /* .uleb128 0x0; Augmentation size */ +#endif + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI4-.LFB3 + .byte 0xe /* DW_CFA_def_cfa_offset */ + .byte 0x8 /* .uleb128 0x8 */ + .byte 0x85 /* DW_CFA_offset, column 0x5 */ + .byte 0x2 /* .uleb128 0x2 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI5-.LCFI4 + .byte 0xd /* DW_CFA_def_cfa_register */ + .byte 0x5 /* .uleb128 0x5 */ + .byte 0x4 /* DW_CFA_advance_loc4 */ + .long .LCFI6-.LCFI5 + .byte 0x86 /* DW_CFA_offset, column 0x6 */ + .byte 0x3 /* .uleb128 0x3 */ + .align 4 +.LEFDE3: + +#endif #endif /* ifndef __x86_64__ */ diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S index bc2812cf8f8..496953e4344 100644 --- a/libffi/src/x86/win32.S +++ b/libffi/src/x86/win32.S @@ -257,3 +257,117 @@ sc_epilogue: ret .ffi_call_STDCALL_end: + + .globl _ffi_closure_SYSV +_ffi_closure_SYSV: + pushl %ebp + movl %esp, %ebp + subl $40, %esp + leal -24(%ebp), %edx + movl %edx, -12(%ebp) /* resp */ + leal 8(%ebp), %edx + movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ + leal -12(%ebp), %edx + movl %edx, (%esp) /* &resp */ + call _ffi_closure_SYSV_inner + movl -12(%ebp), %ecx + cmpl $FFI_TYPE_INT, %eax + je .Lcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lcls_retllong + cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */ + je .Lcls_retstruct1 + cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */ + je .Lcls_retstruct2 +.Lcls_epilogue: + movl %ebp, %esp + popl %ebp + ret +.Lcls_retint: + movl (%ecx), %eax + jmp .Lcls_epilogue +.Lcls_retfloat: + flds (%ecx) + jmp .Lcls_epilogue +.Lcls_retdouble: + fldl (%ecx) + jmp .Lcls_epilogue +.Lcls_retldouble: + fldt (%ecx) + jmp .Lcls_epilogue +.Lcls_retllong: + movl (%ecx), %eax + movl 4(%ecx), %edx + jmp .Lcls_epilogue +.Lcls_retstruct1: + movsbl (%ecx), %eax + jmp .Lcls_epilogue +.Lcls_retstruct2: + movswl (%ecx), %eax + jmp .Lcls_epilogue +.ffi_closure_SYSV_end: + +#if !FFI_NO_RAW_API + +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) +#define CIF_FLAGS_OFFSET 20 + + .balign 16 + .globl _ffi_closure_raw_SYSV +_ffi_closure_raw_SYSV: + pushl %ebp + movl %esp, %ebp + pushl %esi + subl $36, %esp + movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ + movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ + movl %edx, 12(%esp) /* user_data */ + leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ + movl %edx, 8(%esp) /* raw_args */ + leal -24(%ebp), %edx + movl %edx, 4(%esp) /* &res */ + movl %esi, (%esp) /* cif */ + call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ + movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ + cmpl $FFI_TYPE_INT, %eax + je .Lrcls_retint + cmpl $FFI_TYPE_FLOAT, %eax + je .Lrcls_retfloat + cmpl $FFI_TYPE_DOUBLE, %eax + je .Lrcls_retdouble + cmpl $FFI_TYPE_LONGDOUBLE, %eax + je .Lrcls_retldouble + cmpl $FFI_TYPE_SINT64, %eax + je .Lrcls_retllong +.Lrcls_epilogue: + addl $36, %esp + popl %esi + popl %ebp + ret +.Lrcls_retint: + movl -24(%ebp), %eax + jmp .Lrcls_epilogue +.Lrcls_retfloat: + flds -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retdouble: + fldl -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retldouble: + fldt -24(%ebp) + jmp .Lrcls_epilogue +.Lrcls_retllong: + movl -24(%ebp), %eax + movl -20(%ebp), %edx + jmp .Lrcls_epilogue +.ffi_closure_raw_SYSV_end: + +#endif |