Pass -no-pie to GCC
authorBen Gamari <bgamari.foss@gmail.com>
Thu, 10 Nov 2016 18:18:09 +0000 (13:18 -0500)
committerBen Gamari <ben@smart-cactus.org>
Thu, 10 Nov 2016 18:21:09 +0000 (13:21 -0500)
Certain distributions (e.g. Debian and Ubuntu) have enabled PIE be
default in their GCC packaging. This breaks our abuse of GCC as a linker
which requires that we pass -Wl,-r, which is incompatible with
PIE (since the former implies that we are generating a relocatable
object file and the latter an executable).

Test Plan: Validate

Reviewers: hvr, austin

Subscribers: rwbarton, thomie, erikd

Differential Revision: https://phabricator.haskell.org/D2691

GHC Trac Issues: #12759

aclocal.m4
compiler/main/DriverPipeline.hs
compiler/main/SysTools.hs
configure.ac
distrib/configure.ac.in

index df9d420..3a35fe9 100644 (file)
@@ -1322,6 +1322,24 @@ AC_SUBST(GccIsClang)
 rm -f conftest.txt
 ])
 
+# FP_GCC_SUPPORTS_NO_PIE
+# ----------------------
+# Does gcc support the -no-pie option? If so we should pass it to gcc when
+# joining objects since -pie may be enabled by default.
+AC_DEFUN([FP_GCC_SUPPORTS_NO_PIE],
+[
+   AC_REQUIRE([AC_PROG_CC])
+   AC_MSG_CHECKING([whether GCC supports -no-pie])
+   echo 'int main() { return 0; }' > conftest.c
+   if ${CC-cc} -o conftest -no-pie conftest.c > /dev/null 2>&1; then
+       AC_DEFINE(GCC_SUPPORTS_NO_PIE, 1, [gcc supports -no-pie])
+       AC_MSG_RESULT([yes])
+   else
+       AC_MSG_RESULT([no])
+   fi
+   rm -f conftest.c conftest.o conftest
+])
+
 dnl Small feature test for perl version. Assumes PerlCmd
 dnl contains path to perl binary.
 dnl
index b578612..23badbd 100644 (file)
@@ -1859,6 +1859,11 @@ linkBinary' staticLink dflags o_files dep_packages = do
                       ++ map SysTools.Option (
                          []
 
+#if GCC_SUPPORTS_NO_PIE
+                      -- See Note [No PIE eating when linking]
+                      ++ ["-no-pie"]
+#endif
+
                       -- Permit the linker to auto link _symbol to _imp_symbol.
                       -- This lets us link against DLLs without needing an "import library".
                       ++ (if platformOS platform == OSMinGW32
@@ -2157,6 +2162,10 @@ joinObjectFiles dflags o_files output_fn = do
                        SysTools.Option "-nostdlib",
                        SysTools.Option "-Wl,-r"
                      ]
+#if GCC_SUPPORTS_NO_PIE
+                        -- See Note [No PIE eating while linking] in SysTools
+                     ++ [SysTools.Option "-no-pie"]
+#endif
                      ++ (if any (cc ==) [Clang, AppleClang, AppleClang51]
                           then []
                           else [SysTools.Option "-nodefaultlibs"])
index 5fb92c8..82a6383 100644 (file)
@@ -1546,6 +1546,15 @@ linesPlatform xs =
 
 #endif
 
+{-
+Note [No PIE eating while linking]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As of 2016 some Linux distributions (e.g. Debian) have started enabling -pie by
+default in their gcc builds. This is incompatible with -r as it implies that we
+are producing an executable. Consequently, we must manually pass -no-pie to gcc
+when joining object files or linking dynamic libraries. See #12759.
+-}
+
 linkDynLib :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
 linkDynLib dflags0 o_files dep_packages
  = do
@@ -1711,6 +1720,10 @@ linkDynLib dflags0 o_files dep_packages
                  ++ [ Option "-o"
                     , FileOption "" output_fn
                     ]
+#if GCC_SUPPORTS_NO_PIE
+                    -- See Note [No PIE eating when linking]
+                 ++ [ Option "-no-pie" ]
+#endif
                  ++ map Option o_files
                  ++ [ Option "-shared" ]
                  ++ map Option bsymbolicFlag
index 70c4447..678fa2e 100644 (file)
@@ -608,6 +608,9 @@ dnl     If gcc, make sure it's at least 3.0
 dnl
 FP_GCC_VERSION
 
+dnl ** See whether gcc supports -no-pie
+FP_GCC_SUPPORTS_NO_PIE
+
 dnl ** look to see if we have a C compiler using an llvm back end.
 dnl
 FP_CC_LLVM_BACKEND
index 0ae716b..e733f64 100644 (file)
@@ -90,6 +90,7 @@ FIND_LD([LdCmd])
 AC_SUBST([LdCmd])
 
 FP_GCC_VERSION
+FP_GCC_SUPPORTS_NO_PIE
 AC_PROG_CPP
 
 FP_PROG_LD_IS_GNU