From e8bd400eb808c84d9a089bc66614bbb49594a121 Mon Sep 17 00:00:00 2001 From: Debian Haskell Group Date: Mon, 14 Nov 2016 16:35:40 +0000 Subject: [PATCH] no-pie Gbp-Pq: Name no-pie --- aclocal.m4 | 21 +++++++++++++++++++++ compiler/main/DriverPipeline.hs | 10 ++++++++++ compiler/main/DynFlags.hs | 1 + compiler/main/SysTools.hs | 15 +++++++++++++++ configure | 20 ++++++++++++++++++++ configure.ac | 3 +++ distrib/configure.ac.in | 1 + settings.in | 1 + 8 files changed, 72 insertions(+) diff --git a/aclocal.m4 b/aclocal.m4 index 8de2f57f..9570cedd 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -502,12 +502,14 @@ AC_DEFUN([FP_SETTINGS], fi SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" + SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE" SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" AC_SUBST(SettingsCCompilerCommand) AC_SUBST(SettingsHaskellCPPCommand) AC_SUBST(SettingsHaskellCPPFlags) AC_SUBST(SettingsCCompilerFlags) AC_SUBST(SettingsCCompilerLinkFlags) + AC_SUBST(SettingsCCompilerSupportsNoPie) AC_SUBST(SettingsLdCommand) AC_SUBST(SettingsLdFlags) AC_SUBST(SettingsArCommand) @@ -1254,6 +1256,25 @@ 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 + CONF_GCC_SUPPORTS_NO_PIE=YES + AC_MSG_RESULT([yes]) + else + CONF_GCC_SUPPORTS_NO_PIE=NO + 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 2f596780..953a4c6b 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -1850,6 +1850,11 @@ linkBinary' staticLink dflags o_files dep_packages = do ++ map SysTools.Option ( [] + -- See Note [No PIE eating when linking] + ++ (if sGccSupportsNoPie mySettings + then ["-no-pie"] + else []) + -- 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 @@ -2147,6 +2152,11 @@ joinObjectFiles dflags o_files output_fn = do SysTools.Option "-nostdlib", SysTools.Option "-Wl,-r" ] + -- See Note [No PIE eating while linking] in SysTools + ++ (if sGccSupportsNoPie mySettings + then [SysTools.Option "-no-pie"] + else []) + ++ (if any (cc ==) [Clang, AppleClang, AppleClang51] then [] else [SysTools.Option "-nodefaultlibs"]) diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 6a4737ee..fbdeebbb 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -943,6 +943,7 @@ data Settings = Settings { sLdSupportsBuildId :: Bool, sLdSupportsFilelist :: Bool, sLdIsGnuLd :: Bool, + sGccSupportsNoPie :: Bool, -- commands for particular phases sPgm_L :: String, sPgm_P :: (String,[Option]), diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs index ed44b102..52868427 100644 --- a/compiler/main/SysTools.hs +++ b/compiler/main/SysTools.hs @@ -252,6 +252,7 @@ initSysTools mbMinusB -- to make that possible, so for now you can't. gcc_prog <- getSetting "C compiler command" gcc_args_str <- getSetting "C compiler flags" + gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie" cpp_prog <- getSetting "Haskell CPP command" cpp_args_str <- getSetting "Haskell CPP flags" let unreg_gcc_args = if targetUnregisterised @@ -344,6 +345,7 @@ initSysTools mbMinusB sLdSupportsBuildId = ldSupportsBuildId, sLdSupportsFilelist = ldSupportsFilelist, sLdIsGnuLd = ldIsGnuLd, + sGccSupportsNoPie = gccSupportsNoPie, sProgramName = "ghc", sProjectVersion = cProjectVersion, sPgm_L = unlit_path, @@ -1601,6 +1603,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] -> [UnitId] -> IO () linkDynLib dflags0 o_files dep_packages = do @@ -1766,6 +1777,10 @@ linkDynLib dflags0 o_files dep_packages ++ [ Option "-o" , FileOption "" output_fn ] + -- See Note [No PIE eating when linking] + ++ (if sGccSupportsNoPie (settings dflags) + then [Option "-no-pie"] + else []) ++ map Option o_files ++ [ Option "-shared" ] ++ map Option bsymbolicFlag diff --git a/configure b/configure index 0d64af4b..572f3c22 100755 --- a/configure +++ b/configure @@ -665,6 +665,7 @@ SettingsPerlCommand SettingsArCommand SettingsLdFlags SettingsLdCommand +SettingsCCompilerSupportsNoPie SettingsCCompilerLinkFlags SettingsCCompilerFlags SettingsHaskellCPPFlags @@ -7976,6 +7977,23 @@ GccVersion=$fp_cv_gcc_version + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC supports -no-pie" >&5 +$as_echo_n "checking whether GCC supports -no-pie... " >&6; } + echo 'int main() { return 0; }' > conftest.c + if ${CC-cc} -o conftest -no-pie conftest.c > /dev/null 2>&1; then + CONF_GCC_SUPPORTS_NO_PIE=YES + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + CONF_GCC_SUPPORTS_NO_PIE=NO + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + rm -f conftest.c conftest.o conftest + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler is clang" >&5 $as_echo_n "checking whether C compiler is clang... " >&6; } $CC -x c /dev/null -dM -E > conftest.txt 2>&1 @@ -9337,6 +9355,7 @@ fi fi SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" + SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE" SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" @@ -9355,6 +9374,7 @@ fi + for ac_prog in gsed sed do # Extract the first word of "$ac_prog", so it can be a program name with args. diff --git a/configure.ac b/configure.ac index 31401d7e..01375bcd 100644 --- a/configure.ac +++ b/configure.ac @@ -647,6 +647,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 c3993528..a93850ea 100644 --- a/distrib/configure.ac.in +++ b/distrib/configure.ac.in @@ -103,6 +103,7 @@ if test "x$BinDistNeedsLibdw" = "xyes" ; then fi FP_GCC_VERSION +FP_GCC_SUPPORTS_NO_PIE AC_PROG_CPP FP_PROG_LD_IS_GNU diff --git a/settings.in b/settings.in index e8cdad34..7ec1c260 100644 --- a/settings.in +++ b/settings.in @@ -2,6 +2,7 @@ ("C compiler command", "@SettingsCCompilerCommand@"), ("C compiler flags", "@SettingsCCompilerFlags@"), ("C compiler link flags", "@SettingsCCompilerLinkFlags@"), + ("C compiler supports -no-pie", "@SettingsCCompilerSupportsNoPie@"), ("Haskell CPP command","@SettingsHaskellCPPCommand@"), ("Haskell CPP flags","@SettingsHaskellCPPFlags@"), ("ld command", "@SettingsLdCommand@"), -- 2.30.2