Richard Henderson <r...@redhat.com> writes: > Upstream libffi has added support for Go closures (using the static chain), > and support for complex numbers. Perhaps less relevant is new support for > arc, microblaze, moxie, nios, and or1k targets. > > Without additional changes for Go, this merge has little effect. Within the > gcc tree libffi is primarily used by libjava. > > Tested with no regressions on {i686,x86_64,ppc64,s390x,aarch64,alpha}-linux. > > Due to upstream breakage, and difficulty debugging on Darwin, > {i686,x86_64}-darwin retains copies of the existing sources and thus remains > 100% unchanged. Since libgo doesn't support darwin, this should cause no > immediate problems.
The patch introduced massive problems on Solaris, both SPARC and x86: * on Solaris/SPARC, /bin/as requires .type fn,#function instead of @function. I've simply commented the affected lines in src/sparc/v[89].S to make progress. * /bin/as doesn't support .macro/.endm. I'm using preprocessor macros instead to implement E in src/sparc/v[89].S and src/x86/{sysv, unix64}.S. * Solaris/x86 /bin/as doesn't support .org, so I've just disabled the uses in src/x86/{sysv, unix64}.S, as on Darwin. * Solaris/x86 /bin/as has different COMDAT syntax; I've disabled it for the moment. * Solaris/x86 needs to use EH_FRAME_FLAGS so manually and compiler generated .eh_frame sections match, otherwise libffi.so fails to link: ld: fatal: file src/.libs/prep_cif.o; section [16].eh_frame and file src/x86/.libs/sysv.o; section [9].eh_frame have incompatibile attributes and cannot be merged into a single output section * Yet unfixed for Solaris/SPARC /bin/as: as: "v8.s", line 128: error: invalid digit in radix 10 as seems to only understand single-digit labels as: "v8.s", line 140: error: statement syntax as: "v8.s", line 157: error: unknown opcode ".rept" as: "v8.s", line 157: error: statement syntax as: "v8.s", line 163: error: unknown opcode ".endr" as: "v8.s", line 163: error: statement syntax and knows nothing about .rept/.endr Here are the hacks I've used to make some progress:
diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S --- a/libffi/src/sparc/v8.S +++ b/libffi/src/sparc/v8.S @@ -48,7 +48,9 @@ #ifndef __GNUC__ .align 8 .globl C(ffi_flush_icache) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_flush_icache),@function +#endif FFI_HIDDEN(C(ffi_flush_icache)) C(ffi_flush_icache): @@ -66,14 +68,17 @@ 1: iflush %o0 .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) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_call_v8),@function +#endif FFI_HIDDEN(C(ffi_call_v8)) C(ffi_call_v8): @@ -114,71 +119,71 @@ 1: add %o7, %l0, %o7 ! o7 = 0b + ret_typ ! 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 srl %o0, 8, %o0 -E SPARC_RET_F_1 +E(SPARC_RET_F_1) st %f0, [%i2] ret restore @@ -231,7 +236,9 @@ 2: .align 8 .globl C(ffi_go_closure_v8) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_go_closure_v8),@function +#endif FFI_HIDDEN(C(ffi_go_closure_v8)) C(ffi_go_closure_v8): @@ -249,7 +256,9 @@ C(ffi_go_closure_v8): .align 8 .globl C(ffi_closure_v8) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_closure_v8),@function +#endif FFI_HIDDEN(C(ffi_closure_v8)) C(ffi_closure_v8): @@ -285,70 +294,70 @@ 1: sll %o0, 4, %o0 ! o0 = o0 * 16 ! 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 --- a/libffi/src/sparc/v9.S +++ b/libffi/src/sparc/v9.S @@ -42,17 +42,20 @@ #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) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_call_v9),@function +#endif FFI_HIDDEN(C(ffi_call_v9)) C(ffi_call_v9): @@ -107,73 +110,73 @@ 1: sll %l1, 4, %l1 .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 +216,9 @@ 8: stx %o1, [%l2+8] .align 8 .globl C(ffi_go_closure_v9) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_go_closure_v9),@function +#endif FFI_HIDDEN(C(ffi_go_closure_v9)) C(ffi_go_closure_v9): @@ -232,7 +237,9 @@ C(ffi_go_closure_v9): .align 8 .globl C(ffi_closure_v9) +#if !(defined(__sun__) && defined(__svr4__)) .type C(ffi_closure_v9),@function +#endif FFI_HIDDEN(C(ffi_closure_v9)) C(ffi_closure_v9): @@ -289,72 +296,72 @@ 1: sll %o0, 4, %o0 ! o2 = i2 * 16 ! 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 --- 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; \ @@ -823,9 +823,9 @@ ENDF(C(__x86.get_pc_thunk.dx)) .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EHFrame0: #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 --- 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
Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University