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__ */