diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 536d6639f3ff372caba4e028c6a872e6c5095829..33fe14ae332212856b0b73584139eb80bb90efac 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 07ac781d2987fb3d0b802fa8002ee95fba81df9d..a6a6e09d06c0d7a4de39edaddee7be39ac67c7be 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 2bf13f6cde7b5ab1947221e3f35eb5b19b88550e..eac8e8fe42e3596bb45ad77a575672a8f3c563bb 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 e0cab345cc1f52924391b36d1cd69dd81d403d59..f982707344f5f3312eb5238431c79a7e1356856c 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 b337aa74c1102fa61925e334e6b40e10f1beda9b..ed02bf38d560070edcce6cb447f20309e20b807b 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 5764971fbe14c3dfc0accdfeb44ed19ecc07fb64..b19bc718b504bf9f6201d2150acd45288ccc11bb 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 633e549c997b35e4467ebaf020fa9bd097954760..e4d5fc31c8a82c47f1c7b504c3070f852bb12273 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 53a4c2b7e98612ed3ced8d17ab3b915d42a6f53a..46759f43498583642745ecb0dd34c71e3a968264 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 bc2812cf8f84ae55fdaade307863a0da3d46eec1..496953e434451e4fee1df80c25fbe817b75d4b15 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