libffi provides functionality for dynamically marshalling arguments to/from C functions. First, make it compile using the cross compiler. Secondly, apply a big patch to the ARM assembly code, which is needed because Apple ships a pre-historic version of the GNU assembler which isn't good at macros. --- ghc-6.10.2.orig/libffi/Makefile 2009-03-31 06:13:16.000000000 +1300 +++ ghc-6.10.2/libffi/Makefile 2009-06-18 15:54:37.000000000 +1200 @@ -79,15 +79,22 @@ stamp.ffi: $(RM) -rf $(LIBFFI_DIR) build $(TAR) -zxf $(LIBFFI_TARBALL) + cat iphone.patch | (cd $(LIBFFI_DIR) && patch -p1) mv $(LIBFFI_DIR) build chmod +x ln PATH=`pwd`:$$PATH; \ export PATH; \ cd build && \ - CC=$(WhatGccIsCalled) $(SHELL) configure \ + CC="$(TARGET_GCC)" \ + AR="$(TARGET_AR)" \ + LD="$(TARGET_LD)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + CPPFLAGS="$(TARGET_CPPFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + $(SHELL) configure \ --enable-static=yes \ --enable-shared=$(EnableShared) \ - --host=$(PLATFORM) --build=$(PLATFORM) + --host=$(PLATFORM) touch $@ ffi.h: stamp.ffi --- ghc-6.10.2.orig/libffi/iphone.patch 1970-01-01 12:00:00.000000000 +1200 +++ ghc-6.10.2/libffi/iphone.patch 2009-06-18 15:54:37.000000000 +1200 @@ -0,0 +1,187 @@ +--- build.orig/src/arm/sysv.S 2008-02-27 08:01:52.000000000 +1300 ++++ build/src/arm/sysv.S 2009-05-22 11:49:57.000000000 +1200 +@@ -29,17 +29,6 @@ + #include + #ifdef HAVE_MACHINE_ASM_H + #include +-#else +-#ifdef __USER_LABEL_PREFIX__ +-#define CONCAT1(a, b) CONCAT2(a, b) +-#define CONCAT2(a, b) a ## b +- +-/* Use the right prefix for global labels. */ +-#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +-#else +-#define CNAME(x) x +-#endif +-#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): + #endif + + #ifdef __ELF__ +@@ -83,54 +72,29 @@ + # define call_reg(x) mov lr, pc ; mov pc, x + #endif + +-/* Conditionally compile unwinder directives. */ +-#ifdef __ARM_EABI__ +-#define UNWIND +-#else +-#define UNWIND @ +-#endif +- +- + #if defined(__thumb__) && !defined(__THUMB_INTERWORK__) +-.macro ARM_FUNC_START name +- .text +- .align 0 +- .thumb +- .thumb_func +- ENTRY(\name) +- bx pc +- nop +- .arm +- UNWIND .fnstart +-/* A hook to tell gdb that we've switched to ARM mode. Also used to call +- directly from other local arm routines. */ +-_L__\name: +-.endm +-#else +-.macro ARM_FUNC_START name +- .text +- .align 0 +- .arm +- ENTRY(\name) +- UNWIND .fnstart +-.endm ++#define ARM_FUNC_START(name) \ ++ .text ; \ ++ .align 0 ; \ ++ .thumb ; \ ++ .thumb_func ; \ ++ .globl _ ## name ; \ ++_ ## name: ; \ ++ bx pc ; \ ++ nop ; \ ++ .arm ; \ ++_L__\name: ++ ++#else ++#define ARM_FUNC_START(name) \ ++ .text ; \ ++ .align 0 ; \ ++ .arm ; \ ++ .globl _ ## name ; \ ++_ ## name: + #endif + +-.macro RETLDM regs=, cond=, dirn=ia +-#if defined (__INTERWORKING__) +- .ifc "\regs","" +- ldr\cond lr, [sp], #4 +- .else +- ldm\cond\dirn sp!, {\regs, lr} +- .endif +- bx\cond lr +-#else +- .ifc "\regs","" +- ldr\cond pc, [sp], #4 +- .else +- ldm\cond\dirn sp!, {\regs, pc} +- .endif +-#endif ++.macro RETLDM regs= + .endm + + +@@ -142,16 +106,14 @@ + @ sp+4: fn + + @ This assumes we are using gas. +-ARM_FUNC_START ffi_call_SYSV ++ARM_FUNC_START(ffi_call_SYSV) + @ Save registers +- stmfd sp!, {r0-r3, fp, lr} +- UNWIND .save {r0-r3, fp, lr} +- mov fp, sp ++ stmfd sp!, {r0-r3, r11, lr} ++ mov r11, sp + +- UNWIND .setfp fp, sp + + @ Make room for all of the new args. +- sub sp, fp, r2 ++ sub sp, r11, r2 + + @ Place all of the ffi_prep_args in position + mov ip, r0 +@@ -165,17 +127,17 @@ + ldmia sp, {r0-r3} + + @ and adjust stack +- ldr ip, [fp, #8] ++ ldr ip, [r11, #8] + cmp ip, #16 + movhs ip, #16 + add sp, sp, ip + + @ call (fn) (...) +- ldr ip, [fp, #28] ++ ldr ip, [r11, #28] + call_reg(ip) + + @ Remove the space we pushed for the args +- mov sp, fp ++ mov sp, r11 + + @ Load r2 with the pointer to storage for the return value + ldr r2, [sp, #24] +@@ -216,11 +178,15 @@ + #endif + + LSYM(Lepilogue): +- RETLDM "r0-r3,fp" ++#if defined (__INTERWORKING__) ++ ldmia sp!, {r0-r3,r11,lr} ++ bx lr ++#else ++ ldmia sp!, {r0-r3,r11,pc} ++#endif + + .ffi_call_SYSV_end: +- UNWIND .fnend +- .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) ++ @ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) + + /* + unsigned int FFI_HIDDEN +@@ -230,17 +196,15 @@ + void *args; + */ + +-ARM_FUNC_START ffi_closure_SYSV +- UNWIND .pad #16 ++ARM_FUNC_START(ffi_closure_SYSV) + add ip, sp, #16 + stmfd sp!, {ip, lr} +- UNWIND .save {r0, lr} + add r2, sp, #8 +- .pad #16 ++ @ .pad #16 + sub sp, sp, #16 + str sp, [sp, #8] + add r1, sp, #8 +- bl ffi_closure_SYSV_inner ++ bl _ffi_closure_SYSV_inner + cmp r0, #FFI_TYPE_INT + beq .Lretint + +@@ -291,8 +255,7 @@ + #endif + + .ffi_closure_SYSV_end: +- UNWIND .fnend +- .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) ++ @.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV) + + #if defined __ELF__ && defined __linux__ + .section .note.GNU-stack,"",%progbits