This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[build] Support PIE on Solaris


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.

	Rainer


2015-02-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

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

	libgcc:
	* 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.

	gcc:
	* configure.ac (gcc_cv_ld_pie): Check for -type pie on Solaris
	11.x and 12.
	* configure: Regenerate.

	* gcc.c (LD_PIE_SPEC): Allow redefinition.

	* 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.
	[HAVE_LD_PIE && HAVE_SOLARIS_CRTS] (LD_PIE_SPEC): Define.
	(!(HAVE_LD_PIE && HAVE_SOLARIS_CRTS)] (LINK_PIE_SPEC): Define.
	* config/i386/sol2.h (ENDFILE_SPEC): Remove.
	(ENDFILE_ARCH_SPEC): Define.
	* config/sparc/sol2.h (ENDFILE_ARCH_SPEC): Define.

# HG changeset patch
# Parent 0b3199bc12392bf6e18f8e0824ae4d8d98439b6f
# Parent  f47ad8903880217392a02a0126dcd9b68264c5b7
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,14 @@ 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:crtbeginS.o%s} \
+				 %{" PIE_SPEC ":crtbeginS.o%s} \
+				 %{" NO_PIE_SPEC ":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 +172,27 @@ 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:crtendS.o%s;: \
+			       %{" PIE_SPEC ":crtendS.o%s} \
+			       %{" NO_PIE_SPEC ":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 +265,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 +327,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 LD_PIE_SPEC "-pie %{!mimpure-text:-z text}"
+#else
+/* Solaris ld needs -z type=pie instead of -pie.  */
+#define LD_PIE_SPEC "-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
@@ -4756,10 +4756,19 @@ if test $in_tree_ld = 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
+  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,
diff --git a/gcc/gcc.c b/gcc/gcc.c
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -908,7 +908,9 @@ proper position among the other output f
 
 #ifndef LINK_PIE_SPEC
 #ifdef HAVE_LD_PIE
+#ifndef LD_PIE_SPEC
 #define LD_PIE_SPEC "-pie"
+#endif
 #else
 #define LD_PIE_SPEC ""
 #endif
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
@@ -1046,6 +1046,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
@@ -267,7 +267,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
@@ -280,6 +280,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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]