Recent versions of Solaris 12 ld have gained support for constructor priority. It slightly differs from GNU ld in that .ctors.N/.dtors.N sections aren't handled (no need for backwards compatibility) and .ctors/.dtors aren't merged into .init_array/.fini_array, but kept separate, though their relative execution order remains the same.
The following patch enables init_priority on Solaris if the necessary prerequisites are met: * With the native assemblers, the syntax is slightly different (e.g. @progbits on Solaris/x86 while gas always understands both %progbits and @progbits). * When Solaris ld is in use, the test needs to be modified to remove the .[cd]tors{,.N} sections as explained above. Since the configure check may now depend on the assembler and linker used, it could in theory affect configurations not using gld. Unless I'm mistaken, there are only AIX, HP-UX, and Mac OS X left, all of which define SUPPORTS_INIT_PRIORITY directly and ignore HAVE_INITFINI_ARRAY_SUPPORT. The latter is now always defined with a value, and I've modifed the few users accordingly. IA64 crt{begin,end}.S are the only non-common ones: I haven't tested the patch there, but believe it's obvious. When testing on Solaris/SPARC with the native as, initially bootstrap broke because all .init_array etc. sections were marked SHT_PROGBITS. Once I heeded SECTION_NOTYPE, those errors went away. While doing so, I noticed that HAVE_AS_SPARC_NOBITS is now superfluous since even the Solaris 10 FCS as supports #nobits. Initially, Solaris/SPARC testing gld didn't detect working linker support. It turns out that the gld configure probes the build compiler to enable .init_array/.fini_array support. This test succeeds on Solaris/x86, but fails on Solaris/SPARC. I haven't yet investigated why this happens, and don't fully understand why the test is necessary in the first place. To do proper testing with gld, I've simply configured binutils with --enable-initfini-array. Bootstrapped without regressions on i386-pc-solaris2.1[1-2], sparc-sun-solaris2.1[0-2] with as/ld and gas/gld, and x86_64-pc-linux-gnu. Ok for mainline? I'm not really comfortable with backporting such a change to the gcc-5 branch, though. Rainer 2015-09-10 Rainer Orth <r...@cebitec.uni-bielefeld.de> libgcc: * config/ia64/crtbegin.S: Check HAVE_INITFINI_ARRAY_SUPPORT value. * config/ia64/crtend.S: Likewise. gcc: * acinclude.m4 (gcc_AC_INITFINI_ARRAY): Allow for differences in assembler syntax. Support Solaris ld. Define HAVE_INITFINI_ARRAY_SUPPORT as 0/1. * config/sol2.h (SUPPORTS_INIT_PRIORITY): Define to HAVE_INITFINI_ARRAY_SUPPORT. * config/initfini-array.h: Check HAVE_INITFINI_ARRAY_SUPPORT value. * configure.ac (gcc_cv_as_sparc_nobits): Remove. * config/sparc/sparc.c (sparc_solaris_elf_asm_named_section): Don't check HAVE_AS_SPARC_NOBITS. Heed SECTION_NOTYPE. * configure: Regenerate. * config.in: Regenerate.
# HG changeset patch # Parent a3dd47adc9b6d81669be261d596e66b50d077111 Support init priority on Solaris diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4 --- a/gcc/acinclude.m4 +++ b/gcc/acinclude.m4 @@ -309,43 +309,96 @@ int (*fp) (void) __attribute__ ((section gcc_cv_initfini_array=yes fi elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then - cat > conftest.s <<\EOF -.section .dtors,"a",%progbits + case $target:$gas in + *:yes) + sh_flags='"a"' + sh_type='%progbits' + ;; + i?86-*-solaris2*:no | x86_64-*-solaris2*:no) + sh_flags='"a"' + sh_type='@progbits' + ;; + sparc*-*-solaris2*:no) + sh_flags='#alloc' + sh_type='#progbits' + sh_quote='"' + ;; + esac + case "$target:$gnu_ld" in + *:yes) + cat > conftest.s <<EOF +.section .dtors,$sh_flags,$sh_type .balign 4 .byte 'A', 'A', 'A', 'A' -.section .ctors,"a",%progbits +.section .ctors,$sh_flags,$sh_type .balign 4 .byte 'B', 'B', 'B', 'B' -.section .fini_array.65530,"a",%progbits +.section .fini_array.65530,$sh_flags,$sh_type .balign 4 .byte 'C', 'C', 'C', 'C' -.section .init_array.65530,"a",%progbits +.section .init_array.65530,$sh_flags,$sh_type .balign 4 .byte 'D', 'D', 'D', 'D' -.section .dtors.64528,"a",%progbits +.section .dtors.64528,$sh_flags,$sh_type .balign 4 .byte 'E', 'E', 'E', 'E' -.section .ctors.64528,"a",%progbits +.section .ctors.64528,$sh_flags,$sh_type .balign 4 .byte 'F', 'F', 'F', 'F' -.section .fini_array.01005,"a",%progbits +.section .fini_array.01005,$sh_flags,$sh_type .balign 4 .byte 'G', 'G', 'G', 'G' -.section .init_array.01005,"a",%progbits +.section .init_array.01005,$sh_flags,$sh_type .balign 4 .byte 'H', 'H', 'H', 'H' .text .globl _start _start: EOF - if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ - && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ - && $gcc_cv_objdump -s -j .init_array conftest \ - | grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \ - && $gcc_cv_objdump -s -j .fini_array conftest \ - | grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then - gcc_cv_initfini_array=yes - fi + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .init_array conftest \ + | grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .fini_array conftest \ + | grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then + gcc_cv_initfini_array=yes + fi + ;; + *-*-solaris2*:no) + # When Solaris ld added constructor priority support, it was + # decided to only handle .init_array.N/.fini_array.N since + # there was no need for backwards compatibility with + # .ctors.N/.dtors.N. .ctors/.dtors remain as separate + # sections with correct execution order resp. to + # .init_array/.fini_array, while gld merges them into + # .init_array/.fini_array. + cat > conftest.s <<EOF +.section $sh_quote.fini_array.65530$sh_quote,$sh_flags,$sh_type +.align 4 +.byte 'C', 'C', 'C', 'C' +.section $sh_quote.init_array.65530$sh_quote,$sh_flags,$sh_type +.align 4 +.byte 'D', 'D', 'D', 'D' +.section $sh_quote.fini_array.01005$sh_quote,$sh_flags,$sh_type +.align 4 +.byte 'G', 'G', 'G', 'G' +.section $sh_quote.init_array.01005$sh_quote,$sh_flags,$sh_type +.align 4 +.byte 'H', 'H', 'H', 'H' +.text +.globl _start +_start: +EOF + if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \ + && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .init_array conftest \ + | grep HHHHDDDD > /dev/null 2>&1 \ + && $gcc_cv_objdump -s -j .fini_array conftest \ + | grep GGGGCCCC > /dev/null 2>&1; then + gcc_cv_initfini_array=yes + fi + ;; + esac changequote(,)dnl rm -f conftest conftest.* changequote([,])dnl @@ -375,10 +428,10 @@ changequote([,])dnl fi]) enable_initfini_array=$gcc_cv_initfini_array ]) -if test $enable_initfini_array = yes; then - AC_DEFINE(HAVE_INITFINI_ARRAY_SUPPORT, 1, - [Define .init_array/.fini_array sections are available and working.]) -fi]) +AC_DEFINE_UNQUOTED(HAVE_INITFINI_ARRAY_SUPPORT, + [`if test $enable_initfini_array = yes; then echo 1; else echo 0; fi`], + [Define 0/1 if .init_array/.fini_array sections are available and working.]) +]) dnl # _gcc_COMPUTE_GAS_VERSION dnl # Used by gcc_GAS_VERSION_GTE_IFELSE diff --git a/gcc/config/initfini-array.h b/gcc/config/initfini-array.h --- a/gcc/config/initfini-array.h +++ b/gcc/config/initfini-array.h @@ -23,7 +23,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ -#ifdef HAVE_INITFINI_ARRAY_SUPPORT +#if HAVE_INITFINI_ARRAY_SUPPORT #define USE_INITFINI_ARRAY diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h --- a/gcc/config/sol2.h +++ b/gcc/config/sol2.h @@ -398,11 +398,9 @@ along with GCC; see the file COPYING3. #define NO_DBX_BNSYM_ENSYM 1 #endif -#ifndef USE_GLD -/* The Solaris linker doesn't understand constructor priorities. */ +/* Enable constructor priorities if the configured linker supports it. */ #undef SUPPORTS_INIT_PRIORITY -#define SUPPORTS_INIT_PRIORITY 0 -#endif +#define SUPPORTS_INIT_PRIORITY HAVE_INITFINI_ARRAY_SUPPORT /* Solaris has an implementation of __enable_execute_stack. */ #define HAVE_ENABLE_EXECUTE_STACK diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -9885,14 +9885,12 @@ sparc_solaris_elf_asm_named_section (con if (flags & SECTION_CODE) fputs (",#execinstr", asm_out_file); - /* Sun as only supports #nobits/#progbits since Solaris 10. */ - if (HAVE_AS_SPARC_NOBITS) - { - if (flags & SECTION_BSS) - fputs (",#nobits", asm_out_file); - else - fputs (",#progbits", asm_out_file); - } + if (flags & SECTION_NOTYPE) + ; + else if (flags & SECTION_BSS) + fputs (",#nobits", asm_out_file); + else + fputs (",#progbits", asm_out_file); fputc ('\n', asm_out_file); } diff --git a/gcc/configure.ac b/gcc/configure.ac --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3742,13 +3742,6 @@ AS_HELP_STRING([--disable-fix-cortex-a53 [AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1, [Define if your assembler supports .register.])]) - gcc_GAS_CHECK_FEATURE([@%:@nobits], gcc_cv_as_sparc_nobits,,, - [.section "nobits",#alloc,#write,#nobits - .section "progbits",#alloc,#write,#progbits]) - AC_DEFINE_UNQUOTED(HAVE_AS_SPARC_NOBITS, - [`if test $gcc_cv_as_sparc_nobits = yes; then echo 1; else echo 0; fi`], - [Define to 1 if your assembler supports #nobits, 0 otherwise.]) - gcc_GAS_CHECK_FEATURE([-relax option], gcc_cv_as_sparc_relax,, [-relax], [.text],, [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1, diff --git a/libgcc/config/ia64/crtbegin.S b/libgcc/config/ia64/crtbegin.S --- a/libgcc/config/ia64/crtbegin.S +++ b/libgcc/config/ia64/crtbegin.S @@ -61,7 +61,7 @@ dtor_ptr: .hidden __dso_handle -#ifdef HAVE_INITFINI_ARRAY_SUPPORT +#if HAVE_INITFINI_ARRAY_SUPPORT .section .fini_array, "a" data8 @fptr(__do_global_dtors_aux) diff --git a/libgcc/config/ia64/crtend.S b/libgcc/config/ia64/crtend.S --- a/libgcc/config/ia64/crtend.S +++ b/libgcc/config/ia64/crtend.S @@ -39,7 +39,7 @@ __JCR_END__: data8 0 -#ifdef HAVE_INITFINI_ARRAY_SUPPORT +#if HAVE_INITFINI_ARRAY_SUPPORT .global __do_global_ctors_aux .hidden __do_global_ctors_aux #else /* !HAVE_INITFINI_ARRAY_SUPPORT */
-- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University