From 36035d796755d73bfb62b5b6c6afe19864016dd7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 19 Jan 2015 13:14:59 -0800 Subject: [PATCH] Merge with upstream libffi 3ac1610aa33c887ea9b14935208943925714a33e Includes build fixes for Solaris and Cygwin. From-SVN: r219860 --- libffi/ChangeLog | 4 + libffi/src/sparc/v8.S | 120 ++++++++++++--------- libffi/src/sparc/v9.S | 82 ++++++++------- libffi/src/x86/sysv.S | 10 +- libffi/src/x86/unix64.S | 2 +- libffi/testsuite/libffi.call/pr1172638.c | 127 +++++++++++++++++++++++ 6 files changed, 252 insertions(+), 93 deletions(-) create mode 100644 libffi/testsuite/libffi.call/pr1172638.c diff --git a/libffi/ChangeLog b/libffi/ChangeLog index da17417eab4..dd8d516a42c 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,7 @@ +2015-01-19 Richard Henderson + + * Merge to upstream commit 3ac1610aa33c887ea9b14935208943925714a33e. + 2015-01-19 Richard Henderson PR libffi/64607 diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S index 3a811efe05f..3f483826c1a 100644 --- a/libffi/src/sparc/v8.S +++ b/libffi/src/sparc/v8.S @@ -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 diff --git a/libffi/src/sparc/v9.S b/libffi/src/sparc/v9.S index 52732d364ea..05ef54c3e15 100644 --- a/libffi/src/sparc/v9.S +++ b/libffi/src/sparc/v9.S @@ -42,17 +42,18 @@ #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 diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S index ebbea5d1110..78f245bda07 100644 --- a/libffi/src/x86/sysv.S +++ b/libffi/src/x86/sysv.S @@ -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 diff --git a/libffi/src/x86/unix64.S b/libffi/src/x86/unix64.S index f9f916312c5..c83010c75b5 100644 --- a/libffi/src/x86/unix64.S +++ b/libffi/src/x86/unix64.S @@ -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 index 00000000000..7da1621cd66 --- /dev/null +++ b/libffi/testsuite/libffi.call/pr1172638.c @@ -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); +} -- 2.30.2