diff -r -u ffcall-1.10+2.41.orig/ffcall/avcall/Makefile.devel ffcall-1.10+2.41/ffcall/avcall/Makefile.devel
--- ffcall-1.10+2.41.orig/ffcall/avcall/Makefile.devel	2006-10-13 15:55:29.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/avcall/Makefile.devel	2008-02-22 19:49:04.000000000 +0100
@@ -77,7 +77,7 @@
 	$(RM) avcall-hppa-temp.s
 
 avcall-arm.S : avcall-arm.c avcall.h.in asmarm.sh
-	$(GCC) -V 2.6.3 -b arm-acorn-riscix $(GCCFLAGS) -D__arm__ -S avcall-arm.c -o avcall-arm.s
+	$(GCC) $(GCCFLAGS) -D__arm__ -S avcall-arm.c -o avcall-arm.s
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < avcall-arm.s) > avcall-arm.S
 	$(RM) avcall-arm.s
 
diff -r -u ffcall-1.10+2.41.orig/ffcall/avcall/asmarm.sh ffcall-1.10+2.41/ffcall/avcall/asmarm.sh
--- ffcall-1.10+2.41.orig/ffcall/avcall/asmarm.sh	2006-10-13 15:55:29.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/avcall/asmarm.sh	2008-02-22 19:49:04.000000000 +0100
@@ -25,8 +25,6 @@
 # ----------- Declare global symbols as functions (we have no variables)
 s/\.global	_\([A-Za-z0-9_]*\)$/.global	_\1\
 	DECLARE_FUNCTION(\1)/
-# ----------- Global symbols depends on ASM_UNDERSCORE
-s/_\([A-Za-z0-9_:]*\)/C(\1)/
 EOF
 
 sed -f $tmpscript1 | \
diff -r -u ffcall-1.10+2.41.orig/ffcall/avcall/avcall-arm.c ffcall-1.10+2.41/ffcall/avcall/avcall-arm.c
--- ffcall-1.10+2.41.orig/ffcall/avcall/avcall-arm.c	2006-10-13 15:55:29.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/avcall/avcall-arm.c	2008-02-22 19:49:04.000000000 +0100
@@ -43,6 +43,9 @@
 
   __avword space[__AV_ALIST_WORDS];	/* space for callee's stack frame */
   __avword* argframe = sp;		/* stack offset for argument list */
+
+  /* Make the argument count round up */
+  l->aptr = (__avword*)((void*)l->aptr + sizeof(__avword) - 1);
   int arglen = l->aptr - l->args;
   __avword i;
 
@@ -121,19 +124,14 @@
       }
     } else {
       /* normal struct return convention */
+      /* NB: On arm EABI, structure sizes are NOT necessarily
+       * divisible by 4. */
       if (l->flags & __AV_REGISTER_STRUCT_RETURN) {
-        if (l->rsize == sizeof(char)) { /* can't occur */
-          RETURN(char, i);
-        } else
-        if (l->rsize == sizeof(short)) { /* can't occur */
-          RETURN(short, i);
-        } else
-        if (l->rsize == sizeof(int)) {
-          RETURN(int, i);
-        } else
-        if (l->rsize == 2*sizeof(__avword)) {
+        if (l->rsize >= 0 && l->rsize <= 2*sizeof(__avword)) {
           ((__avword*)l->raddr)[0] = i;
-          ((__avword*)l->raddr)[1] = iret2;
+          if (l->rsize > sizeof(__avword)) {
+            ((__avword*)l->raddr)[1] = iret2;
+          }
         }
       }
     }
diff -r -u ffcall-1.10+2.41.orig/ffcall/avcall/avcall.h.in ffcall-1.10+2.41/ffcall/avcall/avcall.h.in
--- ffcall-1.10+2.41.orig/ffcall/avcall/avcall.h.in	2006-10-13 15:55:29.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/avcall/avcall.h.in	2008-02-22 19:49:04.000000000 +0100
@@ -535,7 +535,7 @@
 #define __av_start_struct3(LIST)  \
   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
 #endif
-#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
+#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4		\
    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)				\
@@ -547,6 +547,12 @@
 #define __av_start_struct3(LIST)  \
   ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
 #endif
+#if defined(__arm__)
+#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
+    (((TYPE_SIZE) < 8) && (TYPE_SPLITTABLE) && (LIST).flags)
+#define __av_start_struct3(LIST)  \
+  ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
+#endif
 #if defined(__alpha__)
 #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8	\
@@ -741,13 +747,18 @@
 /* `long long's are passed embedded on the arg stack. */
 #define av_longlong(LIST,VAL)	__av_longlong(LIST,long long,VAL)
 #define av_ulonglong(LIST,VAL)	__av_longlong(LIST,unsigned long long,VAL)
-#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
+#if defined(__i386__) || defined(__m68k__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
 /* `long long's are (at most) word-aligned. */
 #define __av_longlong(LIST,TYPE,VAL)					\
   (((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST)	\
    ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
 #endif
-#if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__)
+#if defined(__arm__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__)
+#if defined(__arm__)
+#define __av_longlong(LIST,TYPE,VAL)					\
+  (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \
+   ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
+#endif
 /* `long long's have alignment 8. */
 #if defined(__mips__)
 #define __av_longlong(LIST,TYPE,VAL)					\
@@ -787,7 +798,23 @@
 
 /* floating-point argument types */
 
-#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__arm__) || defined(__convex__)
+#if defined(__arm__)
+
+#define av_float(LIST,VAL)						\
+	  (++(LIST).aptr > __av_eptr(LIST)				\
+	      ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
+
+#define av_double(LIST,VAL)						\
+  (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(VAL)+__AV_alignof(VAL)-1) & -(long)__AV_alignof(VAL))) > __av_eptr(LIST)	\
+        ? -1 :								\
+        ((LIST).tmp._double = (double)(VAL),				\
+	      (LIST).aptr[-2] = (LIST).tmp.words[0],			\
+	      (LIST).aptr[-1] = (LIST).tmp.words[1],			\
+	      0));
+
+#endif
+
+#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__convex__)
 
 #define av_float(LIST,VAL)						\
   (++(LIST).aptr > __av_eptr(LIST)					\
@@ -1105,14 +1132,14 @@
 #define __av_struct_alignment(TYPE_ALIGN)  \
   (TYPE_ALIGN)
 #endif
-#if defined(__i386__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__)
+#if defined(__i386__) || defined(__arm__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__)
 /* Structures are passed as fully aligned structures on the arg stack.
  * We align the aptr, store the structure, then fill to word alignment.
  * Single-small-integer structures are NOT promoted to integers and have
  * different alignment.
  */
 /* little endian -> small structures < 1 word are adjusted to the left */
-#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__arm__)
 #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)		\
   (((LIST).aptr =							\
     (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)))\
@@ -1253,7 +1280,7 @@
 	   0))
 #endif
 #endif
-#if defined(__m68k__) || defined(__arm__) || defined(__convex__)
+#if defined(__m68k__) || defined(__convex__)
 /* Structures are passed as embedded copies on the arg stack.
  */
 #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)		\
diff -r -u ffcall-1.10+2.41.orig/ffcall/avcall/tests.c ffcall-1.10+2.41/ffcall/avcall/tests.c
--- ffcall-1.10+2.41.orig/ffcall/avcall/tests.c	2006-10-13 15:55:29.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/avcall/tests.c	2008-02-22 19:49:04.000000000 +0100
@@ -62,6 +62,7 @@
 typedef struct { long l1; long l2; } J;
 typedef struct { char c[3]; } T;
 typedef struct { char c[33],c1; } X;
+typedef struct { T t1; char c; T t2; } M;
 
 char c1='a', c2=127, c3=(char)128, c4=(char)255, c5=-1;
 short s1=32767, s2=(short)32768, s3=3, s4=4, s5=5, s6=6, s7=7, s8=8, s9=9;
@@ -93,6 +94,7 @@
 J J1={47,11},J2={73,55};
 T T1={'t','h','e'},T2={'f','o','x'};
 X X1={"abcdefghijklmnopqrstuvwxyzABCDEF",'G'}, X2={"123",'9'}, X3={"return-return-return",'R'};
+M M1={{'h','e','l'},'o',{'w','o','r'}};
 
 void v_v (void)
 {
@@ -320,6 +322,16 @@
   fflush(out);
   return r;
 }
+M M_M (M a)
+{
+  M r;
+  r.t1 = a.t2;
+  r.c = '!';
+  r.t2 = a.t1;
+  fprintf(out,"M f(M):({\"%c%c%c\"},'%c',{\"%c%c%c\"})",a.t1.c[0],a.t1.c[1],a.t1.c[2],a.c,a.t2.c[0],a.t2.c[1],a.t2.c[2]);
+  fflush(out);
+  return r;
+}
 X X_BcdB (B a, char b, double c, B d)
 {
   static X xr={"return val",'R'};
@@ -746,6 +758,7 @@
   J Jr;
   T Tr;
   X Xr;
+  M Mr;
 
   Ir = I_III(I1,I2,I3);
   fprintf(out,"->{%d}\n",Ir.x);
@@ -822,6 +835,16 @@
   av_call(a);
   fprintf(out,"->{\"%c%c%c\"}\n",Tr.c[0],Tr.c[1],Tr.c[2]);
   fflush(out);
+
+  Mr = M_M(M1);
+  fprintf(out,"->{\"%c%c%c\"},'%c',{\"%c%c%c\"}\n",Mr.t1.c[0],Mr.t1.c[1],Mr.t1.c[2],Mr.c,Mr.t2.c[0],Mr.t2.c[1],Mr.t2.c[2]);
+  fflush(out);
+  Mr.t1.c[0]=Mr.c=Mr.t2.c[0]='\0'; clear_traces();
+  av_start_struct(a,M_M,M,0,&Mr);
+  av_struct(a,M,M1);
+  av_call(a);
+  fprintf(out,"->{\"%c%c%c\"},'%c',{\"%c%c%c\"}\n",Mr.t1.c[0],Mr.t1.c[1],Mr.t1.c[2],Mr.c,Mr.t2.c[0],Mr.t2.c[1],Mr.t2.c[2]);
+  fflush(out);
 #endif
 
   Xr = X_BcdB(B1,c2,d3,B2);
diff -r -u ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/Makefile.devel ffcall-1.10+2.41/ffcall/callback/vacall_r/Makefile.devel
--- ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/Makefile.devel	2006-10-13 15:55:31.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/callback/vacall_r/Makefile.devel	2008-02-22 19:49:04.000000000 +0100
@@ -70,7 +70,7 @@
 	$(GCC) -V 2.6.3 -b hppa1.0-hpux $(GCCFLAGS) -D__hppa__ -S vacall-hppa.c -o vacall-hppa.s
 
 vacall-arm.S : vacall-arm.c vacall_r.h.in asmarm.sh
-	$(GCC) -V 2.6.3 -b arm-acorn-riscix $(GCCFLAGS) -D__arm__ -S vacall-arm.c -o vacall-arm.s
+	$(GCC) $(GCCFLAGS) -D__arm__ -S vacall-arm.c -o vacall-arm.s
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < vacall-arm.s) > vacall-arm.S
 	$(RM) vacall-arm.s
 
diff -r -u ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/asmarm.sh ffcall-1.10+2.41/ffcall/callback/vacall_r/asmarm.sh
--- ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/asmarm.sh	2006-10-13 15:55:31.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/callback/vacall_r/asmarm.sh	2008-02-22 19:49:04.000000000 +0100
@@ -25,8 +25,6 @@
 # ----------- Declare global symbols as functions (we have no variables)
 s/\.global	_\([A-Za-z0-9_]*\)$/.global	_\1\
 	DECLARE_FUNCTION(\1)/
-# ----------- Global symbols depends on ASM_UNDERSCORE
-s/_\([A-Za-z0-9_:]*\)/C(\1)/
 EOF
 
 sed -f $tmpscript1 | \
diff -r -u ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/vacall-arm.c ffcall-1.10+2.41/ffcall/callback/vacall_r/vacall-arm.c
--- ffcall-1.10+2.41.orig/ffcall/callback/vacall_r/vacall-arm.c	2006-10-13 15:55:31.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/callback/vacall_r/vacall-arm.c	2008-02-22 19:49:20.000000000 +0100
@@ -22,8 +22,6 @@
 #endif
 register __vaword	iret	__asm__("r0");
 register __vaword	iret2	__asm__("r1");
-register float		fret	__asm__("f0");
-register double		dret	__asm__("f0");
 
 void /* the return type is variable, not void! */
 __vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
@@ -88,10 +86,11 @@
     iret2 = ((__vaword *) &list.tmp._longlong)[1];
   } else
   if (list.rtype == __VAfloat) {
-    fret = list.tmp._float;
+    iret  = ((__vaword *) &list.tmp._float)[0];
   } else
   if (list.rtype == __VAdouble) {
-    dret = list.tmp._double;
+    iret  = ((__vaword *) &list.tmp._double)[0];
+    iret2 = ((__vaword *) &list.tmp._double)[1];
   } else
   if (list.rtype == __VAvoidp) {
     iret = (long)list.tmp._ptr;
diff -r -u ffcall-1.10+2.41.orig/ffcall/vacall/Makefile.devel ffcall-1.10+2.41/ffcall/vacall/Makefile.devel
--- ffcall-1.10+2.41.orig/ffcall/vacall/Makefile.devel	2006-10-13 15:55:32.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/vacall/Makefile.devel	2008-02-22 19:49:04.000000000 +0100
@@ -65,7 +65,7 @@
 	$(GCC) -V 2.6.3 -b hppa1.0-hpux $(GCCFLAGS) -D__hppa__ -S vacall-hppa.c -o vacall-hppa.s
 
 vacall-arm.S : vacall-arm.c vacall.h.in asmarm.sh
-	$(GCC) -V 2.6.3 -b arm-acorn-riscix $(GCCFLAGS) -D__arm__ -S vacall-arm.c -o vacall-arm.s
+	$(GCC) $(GCCFLAGS) -D__arm__ -S vacall-arm.c -o vacall-arm.s
 	(echo '#include "asmarm.h"' ; ./asmarm.sh < vacall-arm.s) > vacall-arm.S
 	$(RM) vacall-arm.s
 
diff -r -u ffcall-1.10+2.41.orig/ffcall/vacall/asmarm.sh ffcall-1.10+2.41/ffcall/vacall/asmarm.sh
--- ffcall-1.10+2.41.orig/ffcall/vacall/asmarm.sh	2006-10-13 15:55:32.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/vacall/asmarm.sh	2008-02-22 19:49:04.000000000 +0100
@@ -25,8 +25,6 @@
 # ----------- Declare global symbols as functions (we have no variables)
 s/\.global	_\([A-Za-z0-9_]*\)$/.global	_\1\
 	DECLARE_FUNCTION(\1)/
-# ----------- Global symbols depends on ASM_UNDERSCORE
-s/_\([A-Za-z0-9_:]*\)/C(\1)/
 EOF
 
 sed -f $tmpscript1 | \
diff -r -u ffcall-1.10+2.41.orig/ffcall/vacall/vacall-arm.c ffcall-1.10+2.41/ffcall/vacall/vacall-arm.c
--- ffcall-1.10+2.41.orig/ffcall/vacall/vacall-arm.c	2006-10-13 15:55:32.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/vacall/vacall-arm.c	2008-02-22 19:49:20.000000000 +0100
@@ -22,8 +22,6 @@
 #endif
 register __vaword	iret	__asm__("r0");
 register __vaword	iret2	__asm__("r1");
-register float		fret	__asm__("f0");
-register double		dret	__asm__("f0");
 
 void /* the return type is variable, not void! */
 __vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
@@ -31,13 +29,11 @@
 {
   struct { long retaddr, arg1, arg2, arg3, arg4; } args;
   __va_alist list;
-  /* MAGIC ALERT!
-   * This is the last struct on the stack, so that
-   * &args + 1 == &return_address == &firstword - 1.
-   * Look at the assembly code to convince yourself.
-   */
   /* Move the arguments passed in registers to their stack locations. */
-  args.retaddr = (&firstword)[-1]; /* save the return address */
+  args.arg1 = (&firstword)[-4];
+  args.arg2 = (&firstword)[-3];
+  args.arg3 = (&firstword)[-2];
+  args.arg4 = (&firstword)[-1];
   (&firstword)[-4] = word1;
   (&firstword)[-3] = word2;
   (&firstword)[-2] = word3;
@@ -88,10 +84,11 @@
     iret2 = ((__vaword *) &list.tmp._longlong)[1];
   } else
   if (list.rtype == __VAfloat) {
-    fret = list.tmp._float;
+    iret  = ((__vaword *) &list.tmp._float)[0];
   } else
   if (list.rtype == __VAdouble) {
-    dret = list.tmp._double;
+    iret  = ((__vaword *) &list.tmp._double)[0];
+    iret2 = ((__vaword *) &list.tmp._double)[1];
   } else
   if (list.rtype == __VAvoidp) {
     iret = (long)list.tmp._ptr;
@@ -103,22 +100,21 @@
       iret = (long) list.raddr;
     } else {
       /* normal struct return convention */
+      /* NB: On arm EABI, structure sizes are NOT necessarily
+       * divisible by 4. */
       if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
-        if (list.rsize == sizeof(char)) { /* can't occur */
-          iret = *(unsigned char *) list.raddr;
-        } else
-        if (list.rsize == sizeof(short)) { /* can't occur */
-          iret = *(unsigned short *) list.raddr;
-        } else
-        if (list.rsize == sizeof(int)) {
-          iret = *(unsigned int *) list.raddr;
-        } else
-        if (list.rsize == 2*sizeof(__vaword)) {
-          iret  = ((__vaword *) list.raddr)[0];
-          iret2 = ((__vaword *) list.raddr)[1];
+        if (list.rsize <= 2*sizeof(__vaword)) {
+         iret = ((__vaword*)list.raddr)[0];
+          if (list.rsize > sizeof(__vaword)) {
+           iret2 = ((__vaword*)list.raddr)[1];
+          }
         }
       }
     }
   }
-  (&firstword)[-1] = args.retaddr; /* restore the return address */
+  /* Restore the stack */
+  (&firstword)[-4] = args.arg1;
+  (&firstword)[-3] = args.arg2;
+  (&firstword)[-2] = args.arg3;
+  (&firstword)[-1] = args.arg4;
 }
diff -r -u ffcall-1.10+2.41.orig/ffcall/vacall/vacall.h.in ffcall-1.10+2.41/ffcall/vacall/vacall.h.in
--- ffcall-1.10+2.41.orig/ffcall/vacall/vacall.h.in	2006-10-13 15:55:32.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/vacall/vacall.h.in	2008-02-22 19:49:20.000000000 +0100
@@ -469,7 +469,7 @@
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
-#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
+#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4		\
    || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)				\
@@ -481,6 +481,12 @@
 #define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
   ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 #endif
+#if defined(__arm__)
+#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
+    (((TYPE_SIZE) < 8) && (TYPE_SPLITTABLE) && ((LIST)->flags))
+#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
+  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
+#endif
 #if defined(__alpha__)
 #define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
   ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8	\
@@ -701,12 +707,12 @@
    (LIST)->aptr + ((-(TYPE_SIZE)) & 3)					\
   )
 #endif
-#if defined(__i386__) || defined(__alpha__) || defined(__ia64__)
+#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__arm__)
 /* little endian -> small args < 1 word are adjusted to the left */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
 #endif
-#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
+#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
 /* big endian -> small args < 1 word are adjusted to the right */
 #define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
   __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
@@ -753,11 +759,11 @@
 /* `long long's are passed embedded on the arg stack. */
 #define va_arg_longlong(LIST)	__va_arg_longlong(LIST,long long)
 #define va_arg_ulonglong(LIST)	__va_arg_longlong(LIST,unsigned long long)
-#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
+#if defined(__i386__) || defined(__m68k__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
 /* `long long's are (at most) word-aligned. */
 #define __va_arg_longlong(LIST,TYPE)	__va_arg(LIST,TYPE)
 #endif
-#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
+#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__arm__) || defined(__m88k__)
 /* `long long's have alignment 8. */
 #define __va_arg_longlong(LIST,TYPE)					\
   ((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
@@ -783,10 +789,10 @@
 
 /* Floating point arguments. */
 
-#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
+#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
 #define __va_align_double(LIST)
 #endif
-#if defined(__mips__) && !defined(__mipsn32__) || defined(__m88k__)
+#if defined(__mips__) && !defined(__mipsn32__) || defined(__m88k__) || defined(__arm__)
 /* __VA_alignof(double) > sizeof(__vaword) */
 #define __va_align_double(LIST)  \
   (LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
--- ffcall-1.10+2.41.orig/ffcall/trampoline/trampoline.c	2006-10-13 15:55:32.000000000 +0200
+++ ffcall-1.10+2.41/ffcall/trampoline/trampoline.c	2008-02-28 16:23:17.000000000 +0100
@@ -11,6 +11,7 @@
 
 
 #include "config.h"
+#undef HAVE_WORKING_MPROTECT
 #include "trampoline.h"
 
 #if defined(__hppa__)
@@ -854,47 +855,50 @@
   ((long *) function)[3]
 #endif
 #ifdef __arm__
-  /* function:
-   *    stmfd   sp!,{r0}			E92D0001
-   *    ldr     r0,[pc,#_data-.-8]		E59F0014
-   *    ldr     ip,[r0,#0]			E590C000
-   *    ldr     r0,[pc,#_variable-.-8]		E59F0010
-   *    str     ip,[r0,#0]			E580C000
-   *    ldmfd   sp!,{r0}^			E8FD0001
-   *    ldr     ip,[pc,#_function-.-8]		E59FC008
-   *    ldr     pc,[ip,#0]			E59CF000
-   * _data:
-   *    .word   <data>				<data>
-   * _variable:
-   *    .word   <variable>			<variable>
-   * _function:
-   *    .word   <address>			<address>
-   */
-  { static long code [8] =
-      { 0xE92D0001, 0xE59F0014, 0xE590C000, 0xE59F0010,
-        0xE580C000, 0xE8FD0001, 0xE59FC008, 0xE59CF000
+  /*
+   *   function:
+   *          stmfd   sp!,{r0}
+   *          ldr     ip,[pc,#_data-.-8]
+   *          ldr     r0,[pc,#_variable-.-8]
+   *          str     ip,[r0,#0]
+   *          ldmfd   sp!,{r0}
+   *          ldr     pc,[pc,#_function-.-8]
+   *   _data:
+   *          .word   0x0
+   *   _variable:
+   *          .word   0x0
+   *   _function:
+   *          .word   0x0
+   */
+  {
+    static long code [6] =
+      {
+	0xe92d0001,
+	0xe59fc00c,
+	0xe59f000c,
+	0xe580c000,
+	0xe8bd0001,
+	0xe59ff004
       };
     int i;
-    for (i=0; i<8; i++) { ((long *) function)[i] = code[i]; }
-    ((long *) function)[8] = (long) data;
-    ((long *) function)[9] = (long) variable;
-    ((long *) function)[10] = (long) address;
+    for (i=0; i<6; i++) { ((long *) function)[i] = code[i]; }
+    ((long *) function)[6] = (long) data;
+    ((long *) function)[7] = (long) variable;
+    ((long *) function)[8] = (long) address;
   }
 #define is_tramp(function)  \
-  ((long *) function)[0] == 0xE92D0001 && \
-  ((long *) function)[1] == 0xE59F0014 && \
-  ((long *) function)[2] == 0xE590C000 && \
-  ((long *) function)[3] == 0xE59F0010 && \
-  ((long *) function)[4] == 0xE580C000 && \
-  ((long *) function)[5] == 0xE8FD0001 && \
-  ((long *) function)[6] == 0xE59FC008 && \
-  ((long *) function)[7] == 0xE59CF000
+  ((long *) function)[0] == 0xe92d0001 && \
+  ((long *) function)[1] == 0xe59fc00c && \
+  ((long *) function)[2] == 0xe59f000c && \
+  ((long *) function)[3] == 0xe580c000 && \
+  ((long *) function)[4] == 0xe8bd0001 && \
+  ((long *) function)[5] == 0xe59ff004
 #define tramp_address(function)  \
-  ((long *) function)[10]
+  ((long *) function)[8]
 #define tramp_variable(function)  \
-  ((long *) function)[9]
+  ((long *) function)[7]
 #define tramp_data(function)  \
-  ((long *) function)[8]
+  ((long *) function)[6]
 #endif
 #ifdef __powerpcsysv4__
   /* function:

