Rainer Orth <r...@cebitec.uni-bielefeld.de> writes:

> Rainer Orth <r...@cebitec.uni-bielefeld.de> writes:
>
>> Beyond the reasons for the bundled Solaris CRTs already cited in
>>
>>      https://gcc.gnu.org/ml/gcc-patches/2015-09/msg01638.html
>>
>> they need to be PIC to support position independent executables (PIE).
>>
>> While linker support for PIE has existed in Solaris ld since at least
>> Solaris 11.2 and GNU ld has just gotten the last (mostly cosmetic) bit
>> for binutils 2.26, there were no usable CRTs before.
>>
>> Now those pieces are in place, this patch enables PIE if the necessary
>> support (linker and CRTs) is detected.  It's mostly straightforward,
>> adapting specs changes in gnu-user.h and allowing for differences in
>> linker options.
>>
>> crtp.o, crtpg.o, and gmon.o are now compiled as PIC to also work with
>> PIE.  I don't thing there's any point to have separate PIC and non-PIC
>> versions here.
>>
>> During early development of the patch, I found that gmon.c includes the
>> trailing NULs in error messages it prints.  Now corrected, though not
>> strictly related to the patch.
>>
>> Contrary to other targets, where -pie seems to be silently ignored if
>> PIE support is missing, I've decided to have gcc error out on Solaris in
>> this situation.  This also allows to easily distinguish between
>> configurations with and without PIE support in the testsuite.  
>>
>> Tested on i386-pc-solaris2.1[012] and sparc-sun-solaris2.1[012] with
>> both as/ld and gas/gld, and x86_64-unknown-linux-gnu.
>>
>> I've also bootstrapped on i386-pc-solaris2.12 and sparc-sun-solaris2.12
>> with --enable-default-pie.  There are a couple of new failures, but they
>> also occur on Linux/x86_64 and I've already filed PRs for (most of?)
>> them.
>>
>> Again, perhaps with exception of the obvious hunk in gcc.c, this patch
>> is purely Solaris-specific, so I'll commit it in a couple of days.  I'd
>> also like to backport it to the gcc-5 branch after some soak time on
>> mainline.
>
> I've now installed both the previous Solaris CRTs patch and this one.  A
> final round of testing revealed a problem with gld PIE support
> detection, though: by mistake I initially did the gas/gld testing with
> an unmodified gld 2.25.  While this works just fine on Solaris/x86 (with
> the exception of the PIE executables not being marked with DF_1_PIE in
> DF_FLAGS_1, a purely informational thing), Solaris/SPARC was different:
> even in a default build, many PIE tests failed with
>
>       gld-2.25: read-only segment has dynamic relocations.
>
> which doesn't happen with a gld 2.25.51 with the Solaris PIE patch.
> Also, Solaris ld links those exact same objects just fine.
>
> Therefore I'm now requiring gld 2.26 on Solaris for PIE support, as in
> the following patchlet.  Tested by configuring with ld, gld 2.25 and a
> gld 2.25.51 faked to call itself gld 2.26 on i386-pc-solaris2.11 and the
> bundled gld 2.23.2 on x86_64-pc-linux-gnu and checking the HAVE_LD_PIE
> is set correctly.
>
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -4751,7 +4751,12 @@ AC_MSG_RESULT($gcc_cv_ld_eh_frame_ciev3)
>  AC_MSG_CHECKING(linker position independent executable support)
>  gcc_cv_ld_pie=no
>  if test $in_tree_ld = yes ; then
> -  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
> +  case "$target" in
> +    # Full PIE support on Solaris was only introduced in gld 2.26.
> +    *-*-solaris2*)  gcc_gld_pie_min_version=26 ;;
> +    *)                   gcc_gld_pie_min_version=15 ;;
> +  esac
> +  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge "$gcc_gld_pie_min_version" -o "$gcc_cv_gld_major_version" -gt 2 \
>       && test $in_tree_ld_is_elf = yes; then
>      gcc_cv_ld_pie=yes
>    fi
> @@ -4759,6 +4764,14 @@ elif test x$gcc_cv_ld != x; then
>    # Check if linker supports -pie option
>    if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
>      gcc_cv_ld_pie=yes
> +    case "$target" in
> +      *-*-solaris2*)
> +     if echo "$ld_ver" | grep GNU > /dev/null \
> +       && test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
> +       gcc_cv_ld_pie=no
> +     fi
> +     ;;
> +    esac
>    else
>      case "$target" in
>        *-*-solaris2.1[[1-9]]*)
> @@ -4772,7 +4785,7 @@ elif test x$gcc_cv_ld != x; then
>  fi
>  if test x"$gcc_cv_ld_pie" = xyes; then
>       AC_DEFINE(HAVE_LD_PIE, 1,
> -[Define if your linker supports -pie option.])
> +[Define if your linker supports PIE option.])
>  fi
>  AC_MSG_RESULT($gcc_cv_ld_pie)
>  
>
> Despite that patch, with --enable-default-pie, there are many failures
> on sparc-sun-solaris2.12 with gas/gld 2.26, both the same error as above
> and execution failures in boehm-gc, libgomp, and libjava.  Given that
> those errors don't occur with as/ld or on i386-pc-solaris2.12, ISTM that
> there's something amiss with gld on Solaris/SPARC.  Given that this is a
> non-recommended and niche configuration, I'm committing the patch
> anyway.

After a week on mainline, I've now backported the Solaris CRTs patch
(which applied as is) and this one to the gcc-5 branch.  This patch
required minor modifications to account for the lack of
--enable-default-pie.  Tested like the mainline patch and committed.

        Rainer


        gcc:
        Backport from mainline
        2015-09-24  Rainer Orth  <r...@cebitec.uni-bielefeld.de>

        * configure.ac (gcc_cv_ld_pie): Check for gld >= 2.26 on Solaris.
        Check for ld -type pie on Solaris 11.x and 12.
        * configure: Regenerate.
        * config.in: Regenerate.

        * config/sol2.h (STARTFILE_CRTBEGIN_SPEC): Define.
        (STARTFILE_SPEC): Use it.
        (ENDFILE_CRTEND_SPEC): Define.
        (ENDFILE_SPEC): Use it and ENDFILE_ARCH_SPEC.
        (SUBTARGET_EXTRA_SPECS): Add STARTFILE_CRTBEGIN_SPEC,
        ENDFILE_ARCH_SPEC, ENDFILE_CRTEND_SPEC.
        (LINK_PIE_SPEC): Define.
        * config/i386/sol2.h (ENDFILE_SPEC): Remove.
        (ENDFILE_ARCH_SPEC): Define.
        * config/sparc/sol2.h (ENDFILE_ARCH_SPEC): Define.

        gcc/testsuite:
        Backport from mainline
        2015-09-24  Rainer Orth  <r...@cebitec.uni-bielefeld.de>

        * lib/target-supports.exp (check_effective_target_pie): Check for
        PIE support on Solaris 11.x and 12.

        libgcc:
        Backport from mainline
        2015-09-24  Rainer Orth  <r...@cebitec.uni-bielefeld.de>

        * config.host (*-*-solaris2*): Add t-crtstuff-pic to tmake_file.
        Add crtbeginS.o, crtendS.o to extra_parts if libgcc_cv_solaris_crts.
        * config/sol2/gmon.c: (monstartup): Don't write trailing NUL of
        messages.
        (internal_mcount): Likewise.
        * config/sol2/t-sol2 (crtp.o, crtpg.o, gmon.o): Compile with
        crt_compile, add CRTSTUFF_T_CFLAGS_S.

# HG changeset patch
# Parent 0b3199bc12392bf6e18f8e0824ae4d8d98439b6f
# Parent  b90d300a04f2c9d148a072a7cc6ec8396ae4abe2
Support PIE on Solaris 12

diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -86,13 +86,10 @@ along with GCC; see the file COPYING3.  
 #endif
 #endif
 
-#undef  ENDFILE_SPEC
-#define ENDFILE_SPEC \
-  "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
-   %{mpc32:crtprec32.o%s} \
+#define ENDFILE_ARCH_SPEC \
+  "%{mpc32:crtprec32.o%s} \
    %{mpc64:crtprec64.o%s} \
-   %{mpc80:crtprec80.o%s} \
-   crtend.o%s crtn.o%s"
+   %{mpc80:crtprec80.o%s}"
 
 #define SUBTARGET_CPU_EXTRA_SPECS \
   { "cpp_subtarget",	 CPP_SUBTARGET_SPEC },		\
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -154,6 +154,12 @@ along with GCC; see the file COPYING3.  
 #define STARTFILE_ARCH_SPEC "%{ansi:values-Xc.o%s} \
 			    %{!ansi:values-Xa.o%s}"
 
+#if defined(HAVE_LD_PIE) && defined(HAVE_SOLARIS_CRTS)
+#define STARTFILE_CRTBEGIN_SPEC "%{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#else
+#define STARTFILE_CRTBEGIN_SPEC	"crtbegin.o%s"
+#endif
+
 /* We don't use the standard svr4 STARTFILE_SPEC because it's wrong for us.  */
 #undef STARTFILE_SPEC
 #ifdef HAVE_SOLARIS_CRTS
@@ -164,21 +170,25 @@ along with GCC; see the file COPYING3.  
 			  %{p:%e-p is not supported; \
 			    pg:crtpg.o%s gmon.o%s; \
 			      :crtp.o%s}}} \
-			crti.o%s %(startfile_arch) \
-			crtbegin.o%s"
+			crti.o%s %(startfile_arch) %(startfile_crtbegin)"
 #else
 #define STARTFILE_SPEC "%{!shared:%{!symbolic: \
 			  %{p:mcrt1.o%s; \
                             pg:gcrt1.o%s gmon.o%s; \
                               :crt1.o%s}}} \
-			crti.o%s %(startfile_arch) \
-			crtbegin.o%s"
+			crti.o%s %(startfile_arch) %(startfile_crtbegin)"
+#endif
+
+#if defined(HAVE_LD_PIE) && defined(HAVE_SOLARIS_CRTS)
+#define ENDFILE_CRTEND_SPEC "%{shared|pie:crtendS.o%s;:crtend.o%s}"
+#else
+#define ENDFILE_CRTEND_SPEC "crtend.o%s"
 #endif
 
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC \
   "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
-   crtend.o%s crtn.o%s"
+   %(endfile_arch) %(endfile_crtend) crtn.o%s"
 
 #undef LINK_ARCH32_SPEC_BASE
 #define LINK_ARCH32_SPEC_BASE \
@@ -251,11 +261,14 @@ along with GCC; see the file COPYING3.  
 
 #undef SUBTARGET_EXTRA_SPECS
 #define SUBTARGET_EXTRA_SPECS \
-  { "startfile_arch",	 STARTFILE_ARCH_SPEC },		\
-  { "link_arch32",       LINK_ARCH32_SPEC },            \
-  { "link_arch64",       LINK_ARCH64_SPEC },            \
-  { "link_arch_default", LINK_ARCH_DEFAULT_SPEC },	\
-  { "link_arch",	 LINK_ARCH_SPEC },		\
+  { "startfile_arch",	 	STARTFILE_ARCH_SPEC },		\
+  { "startfile_crtbegin",	STARTFILE_CRTBEGIN_SPEC },	\
+  { "link_arch32",       	LINK_ARCH32_SPEC },		\
+  { "link_arch64",       	LINK_ARCH64_SPEC },		\
+  { "link_arch_default", 	LINK_ARCH_DEFAULT_SPEC },	\
+  { "link_arch",	 	LINK_ARCH_SPEC },		\
+  { "endfile_arch",	 	ENDFILE_ARCH_SPEC },		\
+  { "endfile_crtend",		ENDFILE_CRTEND_SPEC },	\
   SUBTARGET_CPU_EXTRA_SPECS
 
 /* C++11 programs need -lrt for nanosleep.  */
@@ -310,6 +323,20 @@ along with GCC; see the file COPYING3.  
 #endif /* HAVE_LD_EH_FRAME && TARGET_DL_ITERATE_PHDR */
 #endif
 
+#if defined(HAVE_LD_PIE) && defined(HAVE_SOLARIS_CRTS)
+#ifdef USE_GLD
+/* Assert -z text by default to match Solaris ld.  */
+#define LINK_PIE_SPEC "%{pie:-pie %{!mimpure-text:-z text}} "
+#else
+/* Solaris ld needs -z type=pie instead of -pie.  */
+#define LINK_PIE_SPEC "%{pie:-z type=pie %{mimpure-text:-z textoff}} "
+#endif
+#else
+/* Error out if some part of PIE support is missing.  */
+#define LINK_PIE_SPEC \
+  "%{no-pie:} %{pie:%e-pie is not supported in this configuration} "
+#endif
+
 /* collect2.c can only parse GNU nm -n output.  Solaris nm needs -png to
    produce the same format.  */
 #define NM_FLAGS "-png"
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -280,6 +280,8 @@ extern const char *host_detect_local_cpu
 
 #define SUBTARGET_CPU_EXTRA_SPECS
 
+#define ENDFILE_ARCH_SPEC ""
+
 
 
 /* Register the Solaris-specific #pragma directives.  */
diff --git a/gcc/configure.ac b/gcc/configure.ac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4719,19 +4719,41 @@ AC_MSG_RESULT($gcc_cv_ld_eh_frame_ciev3)
 AC_MSG_CHECKING(linker position independent executable support)
 gcc_cv_ld_pie=no
 if test $in_tree_ld = yes ; then
-  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
+  case "$target" in
+    # Full PIE support on Solaris was only introduced in gld 2.26.
+    *-*-solaris2*)  gcc_gld_pie_min_version=26 ;;
+    *) 		    gcc_gld_pie_min_version=15 ;;
+  esac
+  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge "$gcc_gld_pie_min_version" -o "$gcc_cv_gld_major_version" -gt 2 \
      && test $in_tree_ld_is_elf = yes; then
     gcc_cv_ld_pie=yes
   fi
 elif test x$gcc_cv_ld != x; then
-	# Check if linker supports -pie option
-	if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
-		gcc_cv_ld_pie=yes
+  # Check if linker supports -pie option
+  if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
+    gcc_cv_ld_pie=yes
+    case "$target" in
+      *-*-solaris2*)
+	if echo "$ld_ver" | grep GNU > /dev/null \
+	  && test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
+	  gcc_cv_ld_pie=no
 	fi
+	;;
+    esac
+  else
+    case "$target" in
+      *-*-solaris2.1[[1-9]]*)
+	# Solaris 11.x and Solaris 12 added PIE support.
+	if $gcc_cv_ld -z help 2>&1 | grep -- type.*pie > /dev/null; then
+	  gcc_cv_ld_pie=yes
+	fi
+	;;
+    esac
+  fi
 fi
 if test x"$gcc_cv_ld_pie" = xyes; then
 	AC_DEFINE(HAVE_LD_PIE, 1,
-[Define if your linker supports -pie option.])
+[Define if your linker supports PIE option.])
 fi
 AC_MSG_RESULT($gcc_cv_ld_pie)
 
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -957,6 +957,13 @@ proc check_effective_target_pie { } {
 	 || [istarget *-*-gnu*] } {
 	return 1;
     }
+    if { [istarget *-*-solaris2.1\[1-9\]*] } {
+	# Full PIE support was added in Solaris 11.x and Solaris 12, but gcc
+	# errors out if missing, so check for that.
+	return [check_no_compiler_messages pie executable {
+	    int main (void) { return 0; }
+	} "-pie -fpie"]
+    }
     return 0
 }
 
diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -265,7 +265,7 @@ case ${host} in
 *-*-solaris2*)
   # Unless linker support and dl_iterate_phdr are present,
   # unwind-dw2-fde-dip.c automatically falls back to unwind-dw2-fde.c.
-  tmake_file="$tmake_file sol2/t-sol2 t-eh-dw2-dip t-libgcc-pic t-slibgcc t-slibgcc-elf-ver"
+  tmake_file="$tmake_file sol2/t-sol2 t-eh-dw2-dip t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-elf-ver"
   if test $with_gnu_ld = yes; then
     tmake_file="$tmake_file t-slibgcc-gld"
   else
@@ -278,6 +278,8 @@ case ${host} in
     # Solaris 11.x and 12 provide crt1.o, crti.o, and crtn.o as part of the
     # base system.  crtp.o and crtpg.o implement the compiler-dependent parts.
     extra_parts="$extra_parts crtp.o crtpg.o"
+    # If the Solaris CRTs are present, both ld and gld will have PIE support.
+    extra_parts="$extra_parts crtbeginS.o crtendS.o"
   else
     case ${host} in
       i?86-*-solaris2.1[0-9]* | x86_64-*-solaris2.1[0-9]*)
diff --git a/libgcc/config/sol2/gmon.c b/libgcc/config/sol2/gmon.c
--- a/libgcc/config/sol2/gmon.c
+++ b/libgcc/config/sol2/gmon.c
@@ -114,12 +114,12 @@ monstartup (char *lowpc, char *highpc)
   monsize = (s_textsize / HISTFRACTION) + sizeof (struct phdr);
   buffer = sbrk (monsize);
   if (buffer == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
+    write (STDERR_FILENO, MSG, sizeof (MSG) - 1);
     return;
   }
   froms = sbrk (s_textsize / HASHFRACTION);
   if (froms == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
+    write (STDERR_FILENO, MSG, sizeof (MSG) - 1);
     froms = NULL;
     return;
   }
@@ -131,7 +131,7 @@ monstartup (char *lowpc, char *highpc)
   }
   tos = sbrk (tolimit * sizeof (struct tostruct));
   if (tos == (void *) -1) {
-    write (STDERR_FILENO, MSG, sizeof (MSG));
+    write (STDERR_FILENO, MSG, sizeof (MSG) - 1);
     froms = NULL;
     tos = NULL;
     return;
@@ -429,7 +429,7 @@ internal_mcount (char *selfpc, unsigned 
   profiling++;
 
 #define	TOLIMIT	"mcount: tos overflow\n"
-  write (STDERR_FILENO, TOLIMIT, sizeof (TOLIMIT));
+  write (STDERR_FILENO, TOLIMIT, sizeof (TOLIMIT) - 1);
   goto out;
 }
 
diff --git a/libgcc/config/sol2/t-sol2 b/libgcc/config/sol2/t-sol2
--- a/libgcc/config/sol2/t-sol2
+++ b/libgcc/config/sol2/t-sol2
@@ -18,13 +18,13 @@
 
 # crtp, crtpg build rules
 crtp.o: $(srcdir)/config/sol2/crtp.c
-	$(gcc_compile) -c $<
+	$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $<
 crtpg.o: $(srcdir)/config/sol2/crtpg.c
-	$(gcc_compile) -c $<
+	$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $<
 
 # gmon build rule
 gmon.o:	$(srcdir)/config/sol2/gmon.c
-	$(gcc_compile) -c $<
+	$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $<
 
 # Assemble startup files.
 crt1.o: $(srcdir)/config/$(cpu_type)/sol2-c1.S
-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

Reply via email to