Add -static-pie to GCC driver to create static PIE
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 12 Sep 2017 16:30:28 +0000 (16:30 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Tue, 12 Sep 2017 16:30:28 +0000 (09:30 -0700)
This patch adds -static-pie to GCC driver to create static PIE.  A static
position independent executable (PIE) is similar to static executable,
but can be loaded at any address without a dynamic linker.  All linker
input files must be compiled with -fpie or -fPIE and linker must support
--no-dynamic-linker to avoid linking with dynamic linker.  "-z text" is
also needed to prevent dynamic relocations in read-only segments.

PR driver/81498
* common.opt (-static-pie): New alias.
(shared): Negate static-pie.
(-no-pie): Update help text.
(-pie): Likewise.
(static-pie): New option.
* config/gnu-user.h (GNU_USER_TARGET_STARTFILE_SPEC): Add
-static-pie support.
(GNU_USER_TARGET_ENDFILE_SPEC): Likewise.
(LINK_EH_SPEC): Likewise.
(LINK_GCC_C_SEQUENCE_SPEC): Likewise.
* config/i386/gnu-user.h (GNU_USER_TARGET_LINK_SPEC): Likewise.
* config/i386/gnu-user64.h (GNU_USER_TARGET_LINK_SPEC): Likewise.
* gcc.c (LINK_COMMAND_SPEC): Likewise.
(init_gcc_specs): Likewise.
(init_spec): Likewise.
(display_help): Update help message for -pie.
* doc/invoke.texi: Update -pie, -no-pie and -static.  Document
-static-pie.

From-SVN: r252034

gcc/ChangeLog
gcc/common.opt
gcc/config/gnu-user.h
gcc/config/i386/gnu-user.h
gcc/config/i386/gnu-user64.h
gcc/doc/invoke.texi
gcc/gcc.c

index d73074d..766dd64 100644 (file)
@@ -1,3 +1,25 @@
+2017-09-12  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/81498
+       * common.opt (-static-pie): New alias.
+       (shared): Negate static-pie.
+       (-no-pie): Update help text.
+       (-pie): Likewise.
+       (static-pie): New option.
+       * config/gnu-user.h (GNU_USER_TARGET_STARTFILE_SPEC): Add
+       -static-pie support.
+       (GNU_USER_TARGET_ENDFILE_SPEC): Likewise.
+       (LINK_EH_SPEC): Likewise.
+       (LINK_GCC_C_SEQUENCE_SPEC): Likewise.
+       * config/i386/gnu-user.h (GNU_USER_TARGET_LINK_SPEC): Likewise.
+       * config/i386/gnu-user64.h (GNU_USER_TARGET_LINK_SPEC): Likewise.
+       * gcc.c (LINK_COMMAND_SPEC): Likewise.
+       (init_gcc_specs): Likewise.
+       (init_spec): Likewise.
+       (display_help): Update help message for -pie.
+       * doc/invoke.texi: Update -pie, -no-pie and -static.  Document
+       -static-pie.
+
 2017-09-12  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * config/aarch64/aarch64.md (movsi_aarch64): Remove all '*'.
index 0873fb9..1581ca8 100644 (file)
@@ -352,6 +352,9 @@ Common Alias(pedantic-errors)
 -pie
 Driver Alias(pie)
 
+-static-pie
+Driver Alias(static-pie)
+
 -pipe
 Driver Alias(pipe)
 
@@ -3065,7 +3068,7 @@ x
 Driver Joined Separate
 
 shared
-Driver RejectNegative Negative(pie)
+Driver RejectNegative Negative(static-pie)
 Create a shared library.
 
 shared-libgcc
@@ -3111,11 +3114,15 @@ Driver
 
 no-pie
 Driver RejectNegative Negative(shared)
-Don't create a position independent executable.
+Don't create a dynamically linked position independent executable.
 
 pie
 Driver RejectNegative Negative(no-pie)
-Create a position independent executable.
+Create a dynamically linked position independent executable.
+
+static-pie
+Driver RejectNegative Negative(pie)
+Create a static position independent executable.
 
 z
 Driver Joined Separate
index de605b0..a967b69 100644 (file)
@@ -53,11 +53,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   "%{shared:; \
      pg|p|profile:gcrt1.o%s; \
      static:crt1.o%s; \
-     " PIE_SPEC ":Scrt1.o%s; \
+     static-pie|" PIE_SPEC ":Scrt1.o%s; \
      :crt1.o%s} \
    crti.o%s \
    %{static:crtbeginT.o%s; \
-     shared|" PIE_SPEC ":crtbeginS.o%s; \
+     shared|static-pie|" PIE_SPEC ":crtbeginS.o%s; \
      :crtbegin.o%s} \
    %{fvtable-verify=none:%s; \
      fvtable-verify=preinit:vtv_start_preinit.o%s; \
@@ -70,7 +70,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      :crt1.o%s} \
    crti.o%s \
    %{static:crtbeginT.o%s; \
-     shared|pie:crtbeginS.o%s; \
+     shared|pie|static-pie:crtbeginS.o%s; \
      :crtbegin.o%s} \
    %{fvtable-verify=none:%s; \
      fvtable-verify=preinit:vtv_start_preinit.o%s; \
@@ -92,7 +92,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      fvtable-verify=preinit:vtv_end_preinit.o%s; \
      fvtable-verify=std:vtv_end.o%s} \
    %{static:crtend.o%s; \
-     shared|" PIE_SPEC ":crtendS.o%s; \
+     shared|static-pie|" PIE_SPEC ":crtendS.o%s; \
      :crtend.o%s} \
    crtn.o%s \
    " CRTOFFLOADEND
@@ -102,7 +102,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      fvtable-verify=preinit:vtv_end_preinit.o%s; \
      fvtable-verify=std:vtv_end.o%s} \
    %{static:crtend.o%s; \
-     shared|pie:crtendS.o%s; \
+     shared|pie|static-pie:crtendS.o%s; \
      :crtend.o%s} \
    crtn.o%s \
    " CRTOFFLOADEND
@@ -132,12 +132,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
 
 #if defined(HAVE_LD_EH_FRAME_HDR)
-#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
+#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
 #endif
 
 #undef LINK_GCC_C_SEQUENCE_SPEC
 #define LINK_GCC_C_SEQUENCE_SPEC \
-  "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+  "%{static|static-pie:--start-group} %G %L \
+   %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}}"
 
 /* Use --as-needed -lgcc_s for eh support.  */
 #ifdef HAVE_LD_AS_NEEDED
index a4c88f1..8983dc9 100644 (file)
@@ -77,9 +77,10 @@ along with GCC; see the file COPYING3.  If not see
 #define GNU_USER_TARGET_LINK_SPEC "-m %(link_emulation) %{shared:-shared} \
   %{!shared: \
     %{!static: \
-      %{rdynamic:-export-dynamic} \
-      -dynamic-linker %(dynamic_linker)} \
-      %{static:-static}}"
+      %{!static-pie: \
+       %{rdynamic:-export-dynamic} \
+       -dynamic-linker %(dynamic_linker)}} \
+      %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}}"
 
 #undef LINK_SPEC
 #define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
index 39f5ef6..6fc9eae 100644 (file)
@@ -59,11 +59,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   %{shared:-shared} \
   %{!shared: \
     %{!static: \
-      %{rdynamic:-export-dynamic} \
-      %{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \
-      %{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
-      %{" SPEC_X32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}} \
-    %{static:-static}}"
+      %{!static-static: \
+       %{rdynamic:-export-dynamic} \
+       %{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \
+       %{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
+       %{" SPEC_X32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}}} \
+    %{static:-static} %{static-pie:-static -pie --no-dynamic-linker -z text}}"
 
 #undef LINK_SPEC
 #define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
index 6c844c6..e4cacf2 100644 (file)
@@ -497,7 +497,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Link Options,,Options for Linking}.
 @gccoptlist{@var{object-file-name}  -fuse-ld=@var{linker}  -l@var{library} @gol
 -nostartfiles  -nodefaultlibs  -nostdlib  -pie  -pthread  -rdynamic @gol
--s  -static  -static-libgcc  -static-libstdc++ @gol
+-s  -static -static-pie -static-libgcc  -static-libstdc++ @gol
 -static-libasan  -static-libtsan  -static-liblsan  -static-libubsan @gol
 -static-libmpx  -static-libmpxwrappers @gol
 -shared  -shared-libgcc  -symbolic @gol
@@ -11825,14 +11825,23 @@ GNU Compiler Collection (GCC) Internals}.)
 
 @item -pie
 @opindex pie
-Produce a position independent executable on targets that support it.
-For predictable results, you must also specify the same set of options
-used for compilation (@option{-fpie}, @option{-fPIE},
+Produce a dynamically linked position independent executable on targets
+that support it.  For predictable results, you must also specify the same
+set of options used for compilation (@option{-fpie}, @option{-fPIE},
 or model suboptions) when you specify this linker option.
 
 @item -no-pie
 @opindex no-pie
-Don't produce a position independent executable.
+Don't produce a dynamically linked position independent executable.
+
+@item -static-pie
+@opindex static-pie
+Produce a static position independent executable on targets that support
+it.  A static position independent executable is similar to a static
+executable, but can be loaded at any address without a dynamic linker.
+For predictable results, you must also specify the same set of options
+used for compilation (@option{-fpie}, @option{-fPIE}, or model
+suboptions) when you specify this linker option.
 
 @item -pthread
 @opindex pthread
@@ -11856,8 +11865,9 @@ Remove all symbol table and relocation information from the executable.
 
 @item -static
 @opindex static
-On systems that support dynamic linking, this prevents linking with the shared
-libraries.  On other systems, this option has no effect.
+On systems that support dynamic linking, this overrides @option{-pie}
+and prevents linking with the shared libraries.  On other systems, this
+option has no effect.
 
 @item -shared
 @opindex shared
index f1aad1f..cec3ed5 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1015,9 +1015,10 @@ proper position among the other output files.  */
 #endif
 
 /* -u* was put back because both BSD and SysV seem to support it.  */
-/* %{static|no-pie:} simply prevents an error message:
+/* %{static|no-pie|static-pie:} simply prevents an error message:
    1. If the target machine doesn't handle -static.
    2. If PIE isn't enabled by default.
+   3. If the target machine doesn't handle -static-pie.
  */
 /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    scripts which exist in user specified directories, or in standard
@@ -1035,7 +1036,7 @@ proper position among the other output files.  */
    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
-    %{static|no-pie:} %{L*} %(mfwrap) %(link_libgcc) " \
+    %{static|no-pie|static-pie:} %{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o " CHKP_SPEC " \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
        %:include(libgomp.spec)%(link_gomp)}\
@@ -1670,17 +1671,19 @@ init_gcc_specs (struct obstack *obstack, const char *shared_name,
 {
   char *buf;
 
-  buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
-               "%{!static:%{!static-libgcc:"
 #if USE_LD_AS_NEEDED
+  buf = concat ("%{static|static-libgcc|static-pie:", static_name, " ", eh_name, "}"
+               "%{!static:%{!static-libgcc:%{!static-pie:"
                "%{!shared-libgcc:",
                static_name, " " LD_AS_NEEDED_OPTION " ",
                shared_name, " " LD_NO_AS_NEEDED_OPTION
                "}"
                "%{shared-libgcc:",
                shared_name, "%{!shared: ", static_name, "}"
-               "}"
+               "}}"
 #else
+  buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name, "}"
+               "%{!static:%{!static-libgcc:"
                "%{!shared:"
                "%{!shared-libgcc:", static_name, " ", eh_name, "}"
                "%{shared-libgcc:", shared_name, " ", static_name, "}"
@@ -1788,8 +1791,8 @@ init_spec (void)
                            "-lgcc_eh"
 #ifdef USE_LIBUNWIND_EXCEPTIONS
 # ifdef HAVE_LD_STATIC_DYNAMIC
-                           " %{!static:" LD_STATIC_OPTION "} -lunwind"
-                           " %{!static:" LD_DYNAMIC_OPTION "}"
+                           " %{!static:%{!static-pie:" LD_STATIC_OPTION "}} -lunwind"
+                           " %{!static:%{!static-pie:" LD_DYNAMIC_OPTION "}}"
 # else
                            " -lunwind"
 # endif
@@ -3478,7 +3481,8 @@ display_help (void)
   fputs (_("  -S                       Compile only; do not assemble or link.\n"), stdout);
   fputs (_("  -c                       Compile and assemble, but do not link.\n"), stdout);
   fputs (_("  -o <file>                Place the output into <file>.\n"), stdout);
-  fputs (_("  -pie                     Create a position independent executable.\n"), stdout);
+  fputs (_("  -pie                     Create a dynamically linked position independent\n\
+                           executable.\n"), stdout);
   fputs (_("  -shared                  Create a shared library.\n"), stdout);
   fputs (_("\
   -x <language>            Specify the language of the following input files.\n\