From df2a1cc48b45a5493646e14bcd81eff7d684e15b Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Thu, 24 Sep 2015 09:00:22 +0000 Subject: [PATCH] Support PIE on Solaris 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 gld >= 2.26 on Solaris. Check for ld -type pie on Solaris 11.x and 12. * configure: Regenerate. * config.in: 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. From-SVN: r228078 --- gcc/ChangeLog | 21 +++++++++++ gcc/config.in | 2 +- gcc/config/i386/sol2.h | 9 ++--- gcc/config/sol2.h | 51 +++++++++++++++++++++------ gcc/config/sparc/sol2.h | 2 ++ gcc/configure | 30 +++++++++++++--- gcc/configure.ac | 32 ++++++++++++++--- gcc/gcc.c | 2 ++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/lib/target-supports.exp | 7 ++++ libgcc/ChangeLog | 10 ++++++ libgcc/config.host | 4 ++- libgcc/config.in | 3 ++ libgcc/config/sol2/gmon.c | 8 ++--- libgcc/config/sol2/t-sol2 | 6 ++-- 15 files changed, 158 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e549506e6a9..9c2ad9d5d2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2015-09-24 Rainer Orth + + * 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. + + * 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. + 2015-09-24 Rainer Orth * configure.ac (gcc_cv_solaris_crts): New test. diff --git a/gcc/config.in b/gcc/config.in index a1987cc9bd9..8556986ccfa 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1474,7 +1474,7 @@ #endif -/* Define if your linker supports -pie option. */ +/* Define if your linker supports PIE option. */ #ifndef USED_FOR_TARGET #undef HAVE_LD_PIE #endif diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h index 9b725adc9df..ed963f89201 100644 --- a/gcc/config/i386/sol2.h +++ b/gcc/config/i386/sol2.h @@ -86,13 +86,10 @@ along with GCC; see the file COPYING3. If not see #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 index d31a2513376..f444e48659d 100644 --- a/gcc/config/sol2.h +++ b/gcc/config/sol2.h @@ -154,6 +154,14 @@ along with GCC; see the file COPYING3. If not see #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. If not see %{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. If not see #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. If not see #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 index c169e7c69aa..9912e8c517d 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -280,6 +280,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define SUBTARGET_CPU_EXTRA_SPECS +#define ENDFILE_ARCH_SPEC "" + /* Register the Solaris-specific #pragma directives. */ diff --git a/gcc/configure b/gcc/configure index a32bb64948d..608d2645c4c 100755 --- a/gcc/configure +++ b/gcc/configure @@ -27398,15 +27398,37 @@ $as_echo "$gcc_cv_ld_eh_frame_ciev3" >&6; } $as_echo_n "checking linker position independent executable support... " >&6; } 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 diff --git a/gcc/configure.ac b/gcc/configure.ac index 4f8a44e51f1..65b5d704e3b 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4751,19 +4751,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/gcc.c b/gcc/gcc.c index ef132d6fece..55a725583b8 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -909,7 +909,9 @@ proper position among the other output files. */ #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/ChangeLog b/gcc/testsuite/ChangeLog index c9ffa70d5ad..68f4100e275 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-09-24 Rainer Orth + + * lib/target-supports.exp (check_effective_target_pie): Check for + PIE support on Solaris 11.x and 12. + 2015-09-24 Richard Biener * g++.dg/tree-ssa/restrict3.C: New testcase. diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 3088369ff0b..82697f4e4df 100644 --- 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/ChangeLog b/libgcc/ChangeLog index 559f7726f7f..cc5c2c3903b 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,13 @@ +2015-09-24 Rainer Orth + + * 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. + 2015-09-24 Rainer Orth * configure.ac (libgcc_cv_solaris_crts): New test. diff --git a/libgcc/config.host b/libgcc/config.host index 6c8b97bfc01..2c6475625c9 100644 --- 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.in b/libgcc/config.in index 25aa0d93bab..4d33411e408 100644 --- a/libgcc/config.in +++ b/libgcc/config.in @@ -21,6 +21,9 @@ /* Define if the system-provided CRTs are present on Solaris. */ #undef HAVE_SOLARIS_CRTS +/* Define if the system-provided CRTs are present on Solaris. */ +#undef HAVE_SOLARIS_CRTS + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H diff --git a/libgcc/config/sol2/gmon.c b/libgcc/config/sol2/gmon.c index f6419580a96..81a03468b6e 100644 --- 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 short *frompcindex) 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 index 1f7324af21b..75b05883b14 100644 --- 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 -- 2.30.2