diff -ru gcc-4.0.2.orig/libffi/configure gcc-4.0.2/libffi/configure
--- gcc-4.0.2.orig/libffi/configure	2005-09-28 08:16:38.000000000 +0200
+++ gcc-4.0.2/libffi/configure	2006-03-10 19:40:14.000000000 +0100
@@ -5320,6 +5320,7 @@
 i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;;
 i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
 i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-darwin*) TARGET=X86; TARGETDIR=x86;;
 i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
 i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
 i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
diff -ru gcc-4.0.2.orig/libffi/configure.ac gcc-4.0.2/libffi/configure.ac
--- gcc-4.0.2.orig/libffi/configure.ac	2005-08-19 16:57:22.000000000 +0200
+++ gcc-4.0.2/libffi/configure.ac	2006-03-10 19:40:29.000000000 +0100
@@ -46,6 +46,7 @@
 i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;;
 i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
 i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
+i*86-*-darwin*) TARGET=X86; TARGETDIR=x86;;
 i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
 i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
 i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
diff -ru gcc-4.0.2.orig/libffi/src/prep_cif.c gcc-4.0.2/libffi/src/prep_cif.c
--- gcc-4.0.2.orig/libffi/src/prep_cif.c	2004-03-19 23:34:17.000000000 +0100
+++ gcc-4.0.2/libffi/src/prep_cif.c	2006-03-15 21:06:06.000000000 +0100
@@ -119,7 +119,10 @@
 #ifdef SPARC
       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
 #endif
+#ifdef __APPLE__
+      && (cif->rtype->size > 8)
       )
+#endif
     bytes = STACK_ARG_SIZE(sizeof(void*));
 #endif
 
diff -ru gcc-4.0.2.orig/libffi/src/x86/ffi.c gcc-4.0.2/libffi/src/x86/ffi.c
--- gcc-4.0.2.orig/libffi/src/x86/ffi.c	2004-03-16 20:17:33.000000000 +0100
+++ gcc-4.0.2/libffi/src/x86/ffi.c	2006-03-19 08:49:42.000000000 +0100
@@ -121,7 +121,7 @@
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-#ifndef X86_WIN32
+#if !defined X86_WIN32 && !defined __APPLE__
     case FFI_TYPE_STRUCT:
 #endif
     case FFI_TYPE_SINT64:
@@ -135,7 +135,7 @@
       cif->flags = FFI_TYPE_SINT64;
       break;
 
-#ifdef X86_WIN32
+#if defined X86_WIN32 || defined __APPLE__
     case FFI_TYPE_STRUCT:
       if (cif->rtype->size == 1)
         {
@@ -165,6 +165,10 @@
       break;
     }
 
+#ifdef __APPLE__
+  cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
+
   return FFI_OK;
 }
 
@@ -301,7 +305,7 @@
 	   : : "r"(resp)
 	   : "eax", "edx");
     }
-#ifdef X86_WIN32
+#if defined X86_WIN32 || defined __APPLE__
   else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct  */
     {
       asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");
@@ -310,6 +314,16 @@
     {
       asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");
     }
+#if defined __APPLE__
+  else if (rtype == FFI_TYPE_STRUCT)
+    {
+      asm ("lea -8(%ebp),%esp;"
+	   "pop %esi;"
+	   "pop %edi;"
+	   "pop %ebp;"
+	   "ret $4");
+    }
+#endif
 #endif
 }
 
diff -ru gcc-4.0.2.orig/libffi/src/x86/sysv.S gcc-4.0.2/libffi/src/x86/sysv.S
--- gcc-4.0.2.orig/libffi/src/x86/sysv.S	2003-10-21 21:01:58.000000000 +0200
+++ gcc-4.0.2/libffi/src/x86/sysv.S	2006-03-19 08:47:38.000000000 +0100
@@ -31,18 +31,34 @@
 
 .text
 
+#ifdef __APPLE__
+.globl _ffi_prep_args
+#else
 .globl ffi_prep_args
+#endif
+
 
 	.align 4
+#ifdef __APPLE__
+.globl _ffi_call_SYSV
+#else
 .globl ffi_call_SYSV
         .type    ffi_call_SYSV,@function
+#endif
 
+#ifdef __APPLE__
+_ffi_call_SYSV:
+#else
 ffi_call_SYSV:
+#endif
 .LFB1:
         pushl %ebp
 .LCFI0:
         movl  %esp,%ebp
 .LCFI1:
+#ifdef __APPLE__
+        subl $8,%esp
+#endif
 	/* Make room for all of the new args.  */
 	movl  16(%ebp),%ecx
 	subl  %ecx,%esp
@@ -50,12 +66,19 @@
 	movl  %esp,%eax
 
 	/* Place all of the ffi_prep_args in position  */
+#ifdef __APPLE__
+	subl  $8,%esp
+#endif
 	pushl 12(%ebp)
 	pushl %eax
 	call  *8(%ebp)
 
 	/* Return stack to previous state and call the function  */
+#ifdef __APPLE__
+	addl  $16,%esp	
+#else
 	addl  $8,%esp	
+#endif
 
 	call  *28(%ebp)
 
@@ -112,24 +135,100 @@
 	
 retint64:	
 	cmpl  $FFI_TYPE_SINT64,%ecx
-        jne   retstruct
+        jne   retstruct1b
 	/* Load %ecx with the pointer to storage for the return value  */
 	movl  24(%ebp),%ecx	
 	movl  %eax,0(%ecx)
 	movl  %edx,4(%ecx)
+	jmp   epilogue
+	
+retstruct1b:	
+	cmpl  $FFI_TYPE_SINT8,%ecx
+        jne   retstruct2b
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movb  %al,0(%ecx)
+	jmp   epilogue
+	
+retstruct2b:	
+	cmpl  $FFI_TYPE_SINT16,%ecx
+        jne   retstruct
+	/* Load %ecx with the pointer to storage for the return value  */
+	movl  24(%ebp),%ecx	
+	movw  %ax,0(%ecx)
+	jmp   epilogue
 	
 retstruct:
+	cmpl  $FFI_TYPE_STRUCT,%ecx
+        jne   noretval
 	/* Nothing to do!  */
+#ifdef __APPLE__
+        addl $4,%esp
+        popl %ebp
+        ret
+#endif
 
 noretval:
 epilogue:
+#ifdef __APPLE__
+        addl $8,%esp
+#endif
         movl %ebp,%esp
         popl %ebp
         ret
 .LFE1:
 .ffi_call_SYSV_end:
+#ifndef __APPLE__
         .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif
 
+#ifdef __APPLE__
+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0
+LSCIE1:
+	.long	0x0
+	.byte	0x1
+	.ascii "zR\0"
+	.byte	0x1
+	.byte	0x7c
+	.byte	0x8
+	.byte	0x1
+	.byte	0x10
+	.byte	0xc
+	.byte	0x5
+	.byte	0x4
+	.byte	0x88
+	.byte	0x1
+	.align 2
+LECIE1:
+.globl _ffi_call_SYSV.eh
+_ffi_call_SYSV.eh:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1
+LASFDE1:
+	.long	LASFDE1-EH_frame1
+	.long	.LFB1-.
+	.set L$set$2,.LFE1-.LFB1
+	.long L$set$2
+	.byte	0x0
+	.byte	0x4
+	.set L$set$3,.LCFI0-.LFB1
+	.long L$set$3
+	.byte	0xe
+	.byte	0x8
+	.byte	0x84
+	.byte	0x2
+	.byte	0x4
+	.set L$set$4,.LCFI1-.LCFI0
+	.long L$set$4
+	.byte	0xd
+	.byte	0x4
+	.align 2
+LEFDE1:
+#else
 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
 .Lframe1:
 	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
@@ -180,5 +279,6 @@
 	.byte	0x5	/* .uleb128 0x5 */
 	.align 4
 .LEFDE1:
+#endif
 
 #endif /* ifndef __x86_64__ */
