diff options
-rw-r--r-- | aclocal.m4 | 18 | ||||
-rw-r--r-- | compiler/main/DriverPipeline.hs | 9 | ||||
-rw-r--r-- | compiler/main/SysTools.hs | 13 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | distrib/configure.ac.in | 1 |
5 files changed, 44 insertions, 0 deletions
diff --git a/aclocal.m4 b/aclocal.m4 index df9d42028d..3a35fe9b64 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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 diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index b578612ac4..23badbd885 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -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"]) diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs index 5fb92c8583..82a6383dd5 100644 --- a/compiler/main/SysTools.hs +++ b/compiler/main/SysTools.hs @@ -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 diff --git a/configure.ac b/configure.ac index 70c4447bb9..678fa2e609 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/distrib/configure.ac.in b/distrib/configure.ac.in index 0ae716b112..e733f64bbe 100644 --- a/distrib/configure.ac.in +++ b/distrib/configure.ac.in @@ -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 |