Merge with upstream libffi 3ac1610aa33c887ea9b14935208943925714a33e
authorRichard Henderson <rth@redhat.com>
Mon, 19 Jan 2015 21:14:59 +0000 (13:14 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 19 Jan 2015 21:14:59 +0000 (13:14 -0800)
Includes build fixes for Solaris and Cygwin.

From-SVN: r219860

libffi/ChangeLog
libffi/src/sparc/v8.S
libffi/src/sparc/v9.S
libffi/src/x86/sysv.S
libffi/src/x86/unix64.S
libffi/testsuite/libffi.call/pr1172638.c [new file with mode: 0644]

index da17417eab4baf412155301f927d07f65569fef4..dd8d516a42ce3f18077fddc27ea50a7f14e38abe 100644 (file)
@@ -1,3 +1,7 @@
+2015-01-19  Richard Henderson  <rth@redhat.com>
+
+       * Merge to upstream commit 3ac1610aa33c887ea9b14935208943925714a33e.
+
 2015-01-19  Richard Henderson  <rth@redhat.com>
 
        PR libffi/64607
index 3a811efe05f42d887ec763ff990868082e4cab09..3f483826c1ab98eb2d03b2e96a762a0216ad76c3 100644 (file)
@@ -48,7 +48,7 @@
 #ifndef __GNUC__
         .align 8
        .globl  C(ffi_flush_icache)
-       .type   C(ffi_flush_icache),@function
+       .type   C(ffi_flush_icache),#function
        FFI_HIDDEN(C(ffi_flush_icache))
 
 C(ffi_flush_icache):
@@ -66,14 +66,15 @@ C(ffi_flush_icache):
        .size   C(ffi_flush_icache), . - C(ffi_flush_icache)
 #endif
 
-.macro E index
-       .align  16
-       .org    2b + \index * 16
-.endm
+#if defined(__sun__) && defined(__svr4__)
+# define E(INDEX)      .align 16
+#else
+# define E(INDEX)      .align 16; .org 2b + INDEX * 16
+#endif
 
         .align 8
        .globl  C(ffi_call_v8)
-       .type   C(ffi_call_v8),@function
+       .type   C(ffi_call_v8),#function
        FFI_HIDDEN(C(ffi_call_v8))
 
 C(ffi_call_v8):
@@ -82,6 +83,7 @@ C(ffi_call_v8):
        save    %sp, %o4, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
 
        mov     %i0, %o0                ! copy cif
        add     %sp, 64+32, %o1         ! load args area
@@ -114,71 +116,71 @@ C(ffi_call_v8):
        ! Note that each entry is 4 insns, enforced by the E macro.
        .align  16
 2:
-E SPARC_RET_VOID
+E(SPARC_RET_VOID)
        ret
         restore
-E SPARC_RET_STRUCT
+E(SPARC_RET_STRUCT)
        unimp
-E SPARC_RET_UINT8
+E(SPARC_RET_UINT8)
        and     %o0, 0xff, %o0
        st      %o0, [%i2]
        ret
         restore
-E SPARC_RET_SINT8
+E(SPARC_RET_SINT8)
        sll     %o0, 24, %o0
        b       7f
         sra    %o0, 24, %o0
-E SPARC_RET_UINT16
+E(SPARC_RET_UINT16)
        sll     %o0, 16, %o0
        b       7f
         srl    %o0, 16, %o0
-E SPARC_RET_SINT16
+E(SPARC_RET_SINT16)
        sll     %o0, 16, %o0
        b       7f
         sra    %o0, 16, %o0
-E SPARC_RET_UINT32
+E(SPARC_RET_UINT32)
 7:     st      %o0, [%i2]
        ret
         restore
-E SP_V8_RET_CPLX16
+E(SP_V8_RET_CPLX16)
        sth     %o0, [%i2+2]
        b       9f
         srl    %o0, 16, %o0
-E SPARC_RET_INT64
+E(SPARC_RET_INT64)
        st      %o0, [%i2]
        st      %o1, [%i2+4]
        ret
         restore
-E SPARC_RET_INT128
+E(SPARC_RET_INT128)
        std     %o0, [%i2]
        std     %o2, [%i2+8]
        ret
         restore
-E SPARC_RET_F_8
+E(SPARC_RET_F_8)
        st      %f7, [%i2+7*4]
        nop
        st      %f6, [%i2+6*4]
        nop
-E SPARC_RET_F_6
+E(SPARC_RET_F_6)
        st      %f5, [%i2+5*4]
        nop
        st      %f4, [%i2+4*4]
        nop
-E SPARC_RET_F_4
+E(SPARC_RET_F_4)
        st      %f3, [%i2+3*4]
        nop
        st      %f2, [%i2+2*4]
        nop
-E SPARC_RET_F_2
+E(SPARC_RET_F_2)
        st      %f1, [%i2+4]
        st      %f0, [%i2]
        ret
         restore
-E SP_V8_RET_CPLX8
+E(SP_V8_RET_CPLX8)
        stb     %o0, [%i2+1]
-       b       10f
+       b       0f
         srl    %o0, 8, %o0
-E SPARC_RET_F_1
+E(SPARC_RET_F_1)
        st      %f0, [%i2]
        ret
         restore
@@ -188,7 +190,7 @@ E SPARC_RET_F_1
        ret
         restore
        .align  8
-10:    stb     %o0, [%i2]
+0:     stb     %o0, [%i2]
        ret
         restore
 
@@ -201,17 +203,35 @@ E SPARC_RET_F_1
         sll    %l1, 2, %l0                     ! size * 4
 1:     sll     %l1, 4, %l1                     ! size * 16
        add     %l0, %l1, %l0                   ! size * 20
-       add     %o7, %l0, %o7                   ! o7 = 0b + size*20
+       add     %o7, %l0, %o7                   ! o7 = 8b + size*20
        jmp     %o7+(2f-8b)
         mov    %i5, %g2                        ! load static chain
 2:
-.rept  0x1000
-       call    %i1
-        nop
-       unimp   (. - 2b) / 20
-       ret
+
+/* The Sun assembler doesn't understand .rept 0x1000.  */
+#define rept1                  \
+       call    %i1;            \
+        nop;                   \
+       unimp   (. - 2b) / 20;  \
+       ret;                    \
         restore
-.endr
+
+#define rept16                         \
+       rept1; rept1; rept1; rept1;     \
+       rept1; rept1; rept1; rept1;     \
+       rept1; rept1; rept1; rept1;     \
+       rept1; rept1; rept1; rept1
+
+#define rept256                                \
+       rept16; rept16; rept16; rept16; \
+       rept16; rept16; rept16; rept16; \
+       rept16; rept16; rept16; rept16; \
+       rept16; rept16; rept16; rept16
+
+       rept256; rept256; rept256; rept256
+       rept256; rept256; rept256; rept256
+       rept256; rept256; rept256; rept256
+       rept256; rept256; rept256; rept256
 
        cfi_endproc
        .size   C(ffi_call_v8),. - C(ffi_call_v8)
@@ -231,7 +251,7 @@ E SPARC_RET_F_1
 
        .align 8
        .globl  C(ffi_go_closure_v8)
-       .type   C(ffi_go_closure_v8),@function
+       .type   C(ffi_go_closure_v8),#function
        FFI_HIDDEN(C(ffi_go_closure_v8))
 
 C(ffi_go_closure_v8):
@@ -239,6 +259,7 @@ C(ffi_go_closure_v8):
        save    %sp, -STACKFRAME, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
 
        ld      [%g2+4], %o0                    ! load cif
        ld      [%g2+8], %o1                    ! load fun
@@ -249,7 +270,7 @@ C(ffi_go_closure_v8):
 
        .align 8
        .globl  C(ffi_closure_v8)
-       .type   C(ffi_closure_v8),@function
+       .type   C(ffi_closure_v8),#function
        FFI_HIDDEN(C(ffi_closure_v8))
 
 C(ffi_closure_v8):
@@ -257,6 +278,7 @@ C(ffi_closure_v8):
        save    %sp, -STACKFRAME, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
 
        ld      [%g2+FFI_TRAMPOLINE_SIZE], %o0          ! load cif
        ld      [%g2+FFI_TRAMPOLINE_SIZE+4], %o1        ! load fun
@@ -285,70 +307,70 @@ C(ffi_closure_v8):
        ! Note that each entry is 4 insns, enforced by the E macro.
        .align  16
 2:
-E SPARC_RET_VOID
+E(SPARC_RET_VOID)
        ret
         restore
-E SPARC_RET_STRUCT
+E(SPARC_RET_STRUCT)
        ld      [%i2], %i0
        jmp     %i7+12
         restore
-E SPARC_RET_UINT8
+E(SPARC_RET_UINT8)
        ldub    [%i2+3], %i0
        ret
         restore
-E SPARC_RET_SINT8
+E(SPARC_RET_SINT8)
        ldsb    [%i2+3], %i0
        ret
         restore
-E SPARC_RET_UINT16
+E(SPARC_RET_UINT16)
        lduh    [%i2+2], %i0
        ret
         restore
-E SPARC_RET_SINT16
+E(SPARC_RET_SINT16)
        ldsh    [%i2+2], %i0
        ret
         restore
-E SPARC_RET_UINT32
+E(SPARC_RET_UINT32)
        ld      [%i2], %i0
        ret
         restore
-E SP_V8_RET_CPLX16
+E(SP_V8_RET_CPLX16)
        ld      [%i2], %i0
        ret
         restore
-E SPARC_RET_INT64
+E(SPARC_RET_INT64)
        ldd     [%i2], %i0
        ret
         restore
-E SPARC_RET_INT128
+E(SPARC_RET_INT128)
        ldd     [%i2], %i0
        ldd     [%i2+8], %i2
        ret
         restore
-E SPARC_RET_F_8
+E(SPARC_RET_F_8)
        ld      [%i2+7*4], %f7
        nop
        ld      [%i2+6*4], %f6
        nop
-E SPARC_RET_F_6
+E(SPARC_RET_F_6)
        ld      [%i2+5*4], %f5
        nop
        ld      [%i2+4*4], %f4
        nop
-E SPARC_RET_F_4
+E(SPARC_RET_F_4)
        ld      [%i2+3*4], %f3
        nop
        ld      [%i2+2*4], %f2
        nop
-E SPARC_RET_F_2
+E(SPARC_RET_F_2)
        ldd     [%i2], %f0
        ret
         restore
-E SP_V8_RET_CPLX8
+E(SP_V8_RET_CPLX8)
        lduh    [%i2], %i0
        ret
         restore
-E SPARC_RET_F_1
+E(SPARC_RET_F_1)
        ld      [%i2], %f0
        ret
         restore
index 52732d364ea2d97aa9190f3886d4ad29b98e1608..05ef54c3e158eefa4cb9d880ef6bc110ef38e596 100644 (file)
 #endif
 #define L(Y)   C1(.L, Y)
 
-.macro E index
-       .align  16
-       .org    2b + \index * 16
-.endm
+#if defined(__sun__) && defined(__svr4__)
+# define E(INDEX)      .align 16
+#else
+# define E(INDEX)      .align 16; .org 2b + INDEX * 16
+#endif
 
 #define STACK_BIAS 2047
 
        .text
         .align 8
        .globl  C(ffi_call_v9)
-       .type   C(ffi_call_v9),@function
+       .type   C(ffi_call_v9),#function
        FFI_HIDDEN(C(ffi_call_v9))
 
 C(ffi_call_v9):
@@ -60,6 +61,7 @@ C(ffi_call_v9):
        save    %sp, %o4, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
        
        mov     %i0, %o0                        ! copy cif
        add     %sp, STACK_BIAS+128+48, %o1     ! load args area
@@ -107,73 +109,73 @@ C(ffi_call_v9):
 
        .align  16
 2:
-E SPARC_RET_VOID
+E(SPARC_RET_VOID)
        return  %i7+8
         nop
-E SPARC_RET_STRUCT
+E(SPARC_RET_STRUCT)
        add     %sp, STACK_BIAS-64+128+48, %l2
        sub     %sp, 64, %sp
        b       8f
         stx    %o0, [%l2]
-E SPARC_RET_UINT8
+E(SPARC_RET_UINT8)
        and     %o0, 0xff, %i0
        return  %i7+8
          stx   %o0, [%o2]
-E SPARC_RET_SINT8
+E(SPARC_RET_SINT8)
        sll     %o0, 24, %o0
        sra     %o0, 24, %i0
        return  %i7+8
         stx    %o0, [%o2]
-E SPARC_RET_UINT16
+E(SPARC_RET_UINT16)
        sll     %o0, 16, %o0
        srl     %o0, 16, %i0
        return  %i7+8
         stx    %o0, [%o2]
-E SPARC_RET_SINT16
+E(SPARC_RET_SINT16)
        sll     %o0, 16, %o0
        sra     %o0, 16, %i0
        return  %i7+8
         stx    %o0, [%o2]
-E SPARC_RET_UINT32
+E(SPARC_RET_UINT32)
        srl     %o0, 0, %i0
        return  %i7+8
         stx    %o0, [%o2]
-E SP_V9_RET_SINT32
+E(SP_V9_RET_SINT32)
        sra     %o0, 0, %i0
        return  %i7+8
         stx    %o0, [%o2]
-E SPARC_RET_INT64
+E(SPARC_RET_INT64)
        stx     %o0, [%i2]
        return  %i7+8
         nop
-E SPARC_RET_INT128
+E(SPARC_RET_INT128)
        stx     %o0, [%i2]
        stx     %o1, [%i2+8]
        return  %i7+8
         nop
-E SPARC_RET_F_8
+E(SPARC_RET_F_8)
        st      %f7, [%i2+7*4]
        nop
        st      %f6, [%i2+6*4]
        nop
-E SPARC_RET_F_6
+E(SPARC_RET_F_6)
        st      %f5, [%i2+5*4]
        nop
        st      %f4, [%i2+4*4]
        nop
-E SPARC_RET_F_4
+E(SPARC_RET_F_4)
        std     %f2, [%i2+2*4]
        return  %i7+8
         std    %f0, [%o2]
-E SPARC_RET_F_2
+E(SPARC_RET_F_2)
        return  %i7+8
         std    %f0, [%o2]
-E SP_V9_RET_F_3
+E(SP_V9_RET_F_3)
        st      %f2, [%i2+2*4]
        nop
        st      %f1, [%i2+1*4]
        nop
-E SPARC_RET_F_1
+E(SPARC_RET_F_1)
        return  %i7+8
         st     %f0, [%o2]
 
@@ -213,7 +215,7 @@ E SPARC_RET_F_1
 
        .align 8
        .globl  C(ffi_go_closure_v9)
-       .type   C(ffi_go_closure_v9),@function
+       .type   C(ffi_go_closure_v9),#function
        FFI_HIDDEN(C(ffi_go_closure_v9))
 
 C(ffi_go_closure_v9):
@@ -221,6 +223,7 @@ C(ffi_go_closure_v9):
        save    %sp, -STACKFRAME, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
 
        ldx     [%g5+8], %o0
        ldx     [%g5+16], %o1
@@ -232,7 +235,7 @@ C(ffi_go_closure_v9):
 
        .align 8
        .globl  C(ffi_closure_v9)
-       .type   C(ffi_closure_v9),@function
+       .type   C(ffi_closure_v9),#function
        FFI_HIDDEN(C(ffi_closure_v9))
 
 C(ffi_closure_v9):
@@ -240,6 +243,7 @@ C(ffi_closure_v9):
        save    %sp, -STACKFRAME, %sp
        cfi_def_cfa_register(%fp)
        cfi_window_save
+       cfi_register(%o7, %i7)
 
        ldx     [%g1+FFI_TRAMPOLINE_SIZE], %o0
        ldx     [%g1+FFI_TRAMPOLINE_SIZE+8], %o1
@@ -289,72 +293,72 @@ C(ffi_closure_v9):
        ! that is deallocated by the return.
        .align  16
 2:
-E SPARC_RET_VOID
+E(SPARC_RET_VOID)
        return  %i7+8
         nop
-E SPARC_RET_STRUCT
+E(SPARC_RET_STRUCT)
        ldx     [FP-160], %i0
        ldd     [FP-160], %f0
        b       8f
         ldx    [FP-152], %i1
-E SPARC_RET_UINT8
+E(SPARC_RET_UINT8)
        ldub    [FP-160+7], %i0
        return  %i7+8
         nop
-E SPARC_RET_SINT8
+E(SPARC_RET_SINT8)
        ldsb    [FP-160+7], %i0
        return  %i7+8
         nop
-E SPARC_RET_UINT16
+E(SPARC_RET_UINT16)
        lduh    [FP-160+6], %i0
        return  %i7+8
         nop
-E SPARC_RET_SINT16
+E(SPARC_RET_SINT16)
        ldsh    [FP-160+6], %i0
        return  %i7+8
         nop
-E SPARC_RET_UINT32
+E(SPARC_RET_UINT32)
        lduw    [FP-160+4], %i0
        return  %i7+8
         nop
-E SP_V9_RET_SINT32
+E(SP_V9_RET_SINT32)
        ldsw    [FP-160+4], %i0
        return  %i7+8
         nop
-E SPARC_RET_INT64
+E(SPARC_RET_INT64)
        ldx     [FP-160], %i0
        return  %i7+8
         nop
-E SPARC_RET_INT128
+E(SPARC_RET_INT128)
        ldx     [FP-160], %i0
        ldx     [FP-160+8], %i1
        return  %i7+8
         nop
-E SPARC_RET_F_8
+E(SPARC_RET_F_8)
        ld      [FP-160+7*4], %f7
        nop
        ld      [FP-160+6*4], %f6
        nop
-E SPARC_RET_F_6
+E(SPARC_RET_F_6)
        ld      [FP-160+5*4], %f5
        nop
        ld      [FP-160+4*4], %f4
        nop
-E SPARC_RET_F_4
+E(SPARC_RET_F_4)
        ldd     [FP-160], %f0
        ldd     [FP-160+8], %f2
        return  %i7+8
         nop
-E SPARC_RET_F_2
+E(SPARC_RET_F_2)
        ldd     [FP-160], %f0
        return  %i7+8
         nop
-E SP_V9_RET_F_3
+E(SP_V9_RET_F_3)
        ld      [FP-160+2*4], %f2
        nop
        ld      [FP-160+1*4], %f1
        nop
-E SPARC_RET_F_1
+E(SPARC_RET_F_1)
        ld      [FP-160], %f0
        return  %i7+8
         nop
index ebbea5d1110215c5d30fe2fcb39ed2a12f5deb1d..78f245bda0762dee0f1074eaaad9e33ef918645b 100644 (file)
@@ -65,7 +65,7 @@
    actual table.  The entry points into the table are all 8 bytes.
    The use of ORG asserts that we're at the correct location.  */
 /* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__)
+#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
 # define E(BASE, X)    .balign 8
 #else
 # define E(BASE, X)    .balign 8; .org BASE + X * 8
@@ -793,7 +793,7 @@ ENDF(C(ffi_closure_raw_THISCALL))
         .section __TEXT,__textcoal_nt,coalesced,pure_instructions;     \
         .weak_definition X;                                            \
         .private_extern X
-#elif defined __ELF__
+#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
 # define COMDAT(X)                                                     \
        .section .text.X,"axG",@progbits,X,comdat;                      \
        .globl  X;                                                      \
@@ -822,10 +822,12 @@ ENDF(C(__x86.get_pc_thunk.dx))
 #ifdef __APPLE__
 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
 EHFrame0:
+#elif defined(X86_WIN32)
+.section .eh_frame,"r"
 #elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)
-.section .eh_frame,"a",@unwind
+.section .eh_frame,EH_FRAME_FLAGS,@unwind
 #else
-.section .eh_frame,"a",@progbits
+.section .eh_frame,EH_FRAME_FLAGS,@progbits
 #endif
 
 #ifdef HAVE_AS_X86_PCREL
index f9f916312c5c511ac196094d8774bf8f78e8226c..c83010c75b5f37afc430de8f3e3fdec1b3b231db 100644 (file)
@@ -60,7 +60,7 @@
    actual table.  The entry points into the table are all 8 bytes.
    The use of ORG asserts that we're at the correct location.  */
 /* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
-#if defined(__clang__) || defined(__APPLE__)
+#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
 # define E(BASE, X)    .balign 8
 #else
 # define E(BASE, X)    .balign 8; .org BASE + X * 8
diff --git a/libffi/testsuite/libffi.call/pr1172638.c b/libffi/testsuite/libffi.call/pr1172638.c
new file mode 100644 (file)
index 0000000..7da1621
--- /dev/null
@@ -0,0 +1,127 @@
+/* Area:       ffi_call
+   Purpose:    Reproduce bug found in python ctypes
+   Limitations:        none.
+   PR:         Fedora 1174037  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct {
+  long x;
+  long y;
+} POINT;
+
+typedef struct {
+  long left;
+  long top;
+  long right;
+  long bottom;
+} RECT;
+
+static RECT ABI_ATTR pr_test(int i __UNUSED__, RECT ar __UNUSED__, 
+                            RECT* br __UNUSED__, POINT cp __UNUSED__, 
+                            RECT dr __UNUSED__, RECT *er __UNUSED__, 
+                            POINT fp, RECT gr __UNUSED__)
+{
+  RECT result;
+
+  result.left = fp.x;
+  result.right = fp.y;
+  result.top = fp.x;
+  result.bottom = fp.y;
+
+  return result;
+}
+
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  ffi_type point_type, rect_type;
+  ffi_type *point_type_elements[3];  
+  ffi_type *rect_type_elements[5];  
+  
+  int i;
+  POINT cp, fp;
+  RECT ar, br, dr, er, gr; 
+  RECT *p1, *p2;
+
+  /* This is a hack to get a properly aligned result buffer */
+  RECT *rect_result =
+    (RECT *) malloc (sizeof(RECT));
+
+  point_type.size = 0;
+  point_type.alignment = 0;
+  point_type.type = FFI_TYPE_STRUCT;
+  point_type.elements = point_type_elements;
+  point_type_elements[0] = &ffi_type_slong;
+  point_type_elements[1] = &ffi_type_slong;
+  point_type_elements[2] = NULL;
+
+  rect_type.size = 0;
+  rect_type.alignment = 0;
+  rect_type.type = FFI_TYPE_STRUCT;
+  rect_type.elements = rect_type_elements;
+  rect_type_elements[0] = &ffi_type_slong;
+  rect_type_elements[1] = &ffi_type_slong;
+  rect_type_elements[2] = &ffi_type_slong;
+  rect_type_elements[3] = &ffi_type_slong;
+  rect_type_elements[4] = NULL;
+
+  args[0] = &ffi_type_sint;
+  args[1] = &rect_type;
+  args[2] = &ffi_type_pointer;
+  args[3] = &point_type;
+  args[4] = &rect_type;
+  args[5] = &ffi_type_pointer;
+  args[6] = &point_type;
+  args[7] = &rect_type;
+  
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, ABI_NUM, 8, &rect_type, args) == FFI_OK);
+
+  i = 1;
+  ar.left = 2;
+  ar.right = 3;
+  ar.top = 4;
+  ar.bottom = 5;
+  br.left = 6;
+  br.right = 7;
+  br.top = 8;
+  br.bottom = 9;
+  cp.x = 10;
+  cp.y = 11;
+  dr.left = 12;
+  dr.right = 13;
+  dr.top = 14;
+  dr.bottom = 15;
+  er.left = 16;
+  er.right = 17;
+  er.top = 18;
+  er.bottom = 19;
+  fp.x = 20;
+  fp.y = 21;
+  gr.left = 22;
+  gr.right = 23;
+  gr.top = 24;
+  gr.bottom = 25;
+  
+  values[0] = &i;
+  values[1] = &ar;
+  p1 = &br;
+  values[2] = &p1;
+  values[3] = &cp;
+  values[4] = &dr;
+  p2 = &er;
+  values[5] = &p2;
+  values[6] = &fp;
+  values[7] = &gr;
+
+  ffi_call (&cif, FFI_FN(pr_test), rect_result, values);
+  
+  CHECK(rect_result->top == 20);
+  free (rect_result);
+  exit(0);
+}