Gold on powerpc64 doesn't support old ABI objects, but libffi contains old ABI assembly. This patch modifies those files to support both old and new ABI, and adds a builtin define to powerpc64 gcc that can be used to select between the ABIs in assembly. I figure a define is generally useful, and more robust than trying to duplicate gcc configury in libffi (which could be overridden by CFLAGS anyway). Bootstrapped and regression tested powerpc64-linux. OK to apply mainline?
gcc/ * config/rs6000/linux64.h (TARGET_OS_CPP_BUILTINS): Define _CALL_LINUX. libffi/ * src/powerpc/linux64_closure.S: Add new ABI support. * src/powerpc/linux64.S: Likewise. Index: gcc/config/rs6000/linux64.h =================================================================== --- gcc/config/rs6000/linux64.h (revision 192660) +++ gcc/config/rs6000/linux64.h (working copy) @@ -318,6 +318,8 @@ builtin_define ("__PPC64__"); \ builtin_define ("__powerpc__"); \ builtin_define ("__powerpc64__"); \ + if (!DOT_SYMBOLS) \ + builtin_define ("_CALL_LINUX"); \ builtin_assert ("cpu=powerpc64"); \ builtin_assert ("machine=powerpc64"); \ } \ Index: libffi/src/powerpc/linux64_closure.S =================================================================== --- libffi/src/powerpc/linux64_closure.S (revision 192660) +++ libffi/src/powerpc/linux64_closure.S (working copy) @@ -32,16 +32,24 @@ #ifdef __powerpc64__ FFI_HIDDEN (ffi_closure_LINUX64) - FFI_HIDDEN (.ffi_closure_LINUX64) - .globl ffi_closure_LINUX64, .ffi_closure_LINUX64 + .globl ffi_closure_LINUX64 .section ".opd","aw" .align 3 ffi_closure_LINUX64: +#ifdef _CALL_LINUX + .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 + .type ffi_closure_LINUX64,@function + .text +.L.ffi_closure_LINUX64: +#else + FFI_HIDDEN (.ffi_closure_LINUX64) + .globl .ffi_closure_LINUX64 .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 .size ffi_closure_LINUX64,24 .type .ffi_closure_LINUX64,@function .text .ffi_closure_LINUX64: +#endif .LFB1: # save general regs into parm save area std %r3, 48(%r1) @@ -91,7 +99,11 @@ addi %r6, %r1, 128 # make the call +#ifdef _CALL_LINUX + bl ffi_closure_helper_LINUX64 +#else bl .ffi_closure_helper_LINUX64 +#endif .Lret: # now r3 contains the return type @@ -194,7 +206,11 @@ .LFE1: .long 0 .byte 0,12,0,1,128,0,0,0 +#ifdef _CALL_LINUX + .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 +#else .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 +#endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: Index: libffi/src/powerpc/linux64.S =================================================================== --- libffi/src/powerpc/linux64.S (revision 192660) +++ libffi/src/powerpc/linux64.S (working copy) @@ -30,16 +30,25 @@ #include <ffi.h> #ifdef __powerpc64__ - .hidden ffi_call_LINUX64, .ffi_call_LINUX64 - .globl ffi_call_LINUX64, .ffi_call_LINUX64 + .hidden ffi_call_LINUX64 + .globl ffi_call_LINUX64 .section ".opd","aw" .align 3 ffi_call_LINUX64: +#ifdef _CALL_LINUX + .quad .L.ffi_call_LINUX64,.TOC.@tocbase,0 + .type ffi_call_LINUX64,@function + .text +.L.ffi_call_LINUX64: +#else + .hidden .ffi_call_LINUX64 + .globl .ffi_call_LINUX64 .quad .ffi_call_LINUX64,.TOC.@tocbase,0 .size ffi_call_LINUX64,24 .type .ffi_call_LINUX64,@function .text .ffi_call_LINUX64: +#endif .LFB1: mflr %r0 std %r28, -32(%r1) @@ -58,7 +67,11 @@ /* Call ffi_prep_args64. */ mr %r4, %r1 +#ifdef _CALL_LINUX + bl ffi_prep_args64 +#else bl .ffi_prep_args64 +#endif ld %r0, 0(%r29) ld %r2, 8(%r29) @@ -137,7 +150,11 @@ .LFE1: .long 0 .byte 0,12,0,1,128,4,0,0 +#ifdef _CALL_LINUX + .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 +#else .size .ffi_call_LINUX64,.-.ffi_call_LINUX64 +#endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: -- Alan Modra Australia Development Lab, IBM