diff mbox

[build] Support init priority on Solaris

Message ID yddmvvukalu.fsf@lokon.CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth Oct. 7, 2015, 2:38 p.m. UTC
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  <ro@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.
diff mbox

Patch

# 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 */