Commit fefe02c0 authored by Ben Gamari's avatar Ben Gamari 🐢
Browse files

Pass -no-pie to GCC

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).

This is a second attempt at D2691. This attempt constrasts with D2691 in that
it preserves the "does gcc support -no-pie" flag in settings, allowing this to
be reconfigured by `configure` during installation of a binary distribution.
Thanks for @rwbarton for drawing attention to this issue.

Test Plan: Validate

Reviewers: austin, hvr, erikd

Reviewed By: erikd

Subscribers: thomie, rwbarton, erikd

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

GHC Trac Issues: #12759
parent 3da461d9
...@@ -499,12 +499,14 @@ AC_DEFUN([FP_SETTINGS], ...@@ -499,12 +499,14 @@ AC_DEFUN([FP_SETTINGS],
fi fi
SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2" SettingsCCompilerFlags="$CONF_CC_OPTS_STAGE2"
SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2" SettingsCCompilerLinkFlags="$CONF_GCC_LINKER_OPTS_STAGE2"
SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE"
SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2" SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2"
AC_SUBST(SettingsCCompilerCommand) AC_SUBST(SettingsCCompilerCommand)
AC_SUBST(SettingsHaskellCPPCommand) AC_SUBST(SettingsHaskellCPPCommand)
AC_SUBST(SettingsHaskellCPPFlags) AC_SUBST(SettingsHaskellCPPFlags)
AC_SUBST(SettingsCCompilerFlags) AC_SUBST(SettingsCCompilerFlags)
AC_SUBST(SettingsCCompilerLinkFlags) AC_SUBST(SettingsCCompilerLinkFlags)
AC_SUBST(SettingsCCompilerSupportsNoPie)
AC_SUBST(SettingsLdCommand) AC_SUBST(SettingsLdCommand)
AC_SUBST(SettingsLdFlags) AC_SUBST(SettingsLdFlags)
AC_SUBST(SettingsArCommand) AC_SUBST(SettingsArCommand)
...@@ -1258,6 +1260,25 @@ AC_SUBST(GccIsClang) ...@@ -1258,6 +1260,25 @@ AC_SUBST(GccIsClang)
rm -f conftest.txt 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 Small feature test for perl version. Assumes PerlCmd
dnl contains path to perl binary. dnl contains path to perl binary.
dnl dnl
......
...@@ -1850,6 +1850,11 @@ linkBinary' staticLink dflags o_files dep_packages = do ...@@ -1850,6 +1850,11 @@ linkBinary' staticLink dflags o_files dep_packages = do
++ map SysTools.Option ( ++ 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. -- Permit the linker to auto link _symbol to _imp_symbol.
-- This lets us link against DLLs without needing an "import library". -- This lets us link against DLLs without needing an "import library".
++ (if platformOS platform == OSMinGW32 ++ (if platformOS platform == OSMinGW32
...@@ -2151,6 +2156,11 @@ joinObjectFiles dflags o_files output_fn = do ...@@ -2151,6 +2156,11 @@ joinObjectFiles dflags o_files output_fn = do
SysTools.Option "-nostdlib", SysTools.Option "-nostdlib",
SysTools.Option "-Wl,-r" 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] ++ (if any (cc ==) [Clang, AppleClang, AppleClang51]
then [] then []
else [SysTools.Option "-nodefaultlibs"]) else [SysTools.Option "-nodefaultlibs"])
......
...@@ -947,6 +947,7 @@ data Settings = Settings { ...@@ -947,6 +947,7 @@ data Settings = Settings {
sLdSupportsBuildId :: Bool, sLdSupportsBuildId :: Bool,
sLdSupportsFilelist :: Bool, sLdSupportsFilelist :: Bool,
sLdIsGnuLd :: Bool, sLdIsGnuLd :: Bool,
sGccSupportsNoPie :: Bool,
-- commands for particular phases -- commands for particular phases
sPgm_L :: String, sPgm_L :: String,
sPgm_P :: (String,[Option]), sPgm_P :: (String,[Option]),
......
...@@ -251,6 +251,7 @@ initSysTools mbMinusB ...@@ -251,6 +251,7 @@ initSysTools mbMinusB
-- to make that possible, so for now you can't. -- to make that possible, so for now you can't.
gcc_prog <- getSetting "C compiler command" gcc_prog <- getSetting "C compiler command"
gcc_args_str <- getSetting "C compiler flags" gcc_args_str <- getSetting "C compiler flags"
gccSupportsNoPie <- getBooleanSetting "C compiler supports -no-pie"
cpp_prog <- getSetting "Haskell CPP command" cpp_prog <- getSetting "Haskell CPP command"
cpp_args_str <- getSetting "Haskell CPP flags" cpp_args_str <- getSetting "Haskell CPP flags"
let unreg_gcc_args = if targetUnregisterised let unreg_gcc_args = if targetUnregisterised
...@@ -343,6 +344,7 @@ initSysTools mbMinusB ...@@ -343,6 +344,7 @@ initSysTools mbMinusB
sLdSupportsBuildId = ldSupportsBuildId, sLdSupportsBuildId = ldSupportsBuildId,
sLdSupportsFilelist = ldSupportsFilelist, sLdSupportsFilelist = ldSupportsFilelist,
sLdIsGnuLd = ldIsGnuLd, sLdIsGnuLd = ldIsGnuLd,
sGccSupportsNoPie = gccSupportsNoPie,
sProgramName = "ghc", sProgramName = "ghc",
sProjectVersion = cProjectVersion, sProjectVersion = cProjectVersion,
sPgm_L = unlit_path, sPgm_L = unlit_path,
...@@ -858,7 +860,7 @@ getLinkerInfo' dflags = do ...@@ -858,7 +860,7 @@ getLinkerInfo' dflags = do
-- Note [Windows stack usage] -- Note [Windows stack usage]
-- Force static linking of libGCC -- Force static linking of libGCC
-- Note [Windows static libGCC] -- Note [Windows static libGCC]
, "-Xlinker", "--stack=0x800000,0x800000", "-static-libgcc" ] , "-static-libgcc" ]
_ -> do _ -> do
-- In practice, we use the compiler as the linker here. Pass -- In practice, we use the compiler as the linker here. Pass
-- -Wl,--version to get linker version info. -- -Wl,--version to get linker version info.
...@@ -1578,6 +1580,15 @@ linesPlatform xs = ...@@ -1578,6 +1580,15 @@ linesPlatform xs =
#endif #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 :: DynFlags -> [String] -> [UnitId] -> IO ()
linkDynLib dflags0 o_files dep_packages linkDynLib dflags0 o_files dep_packages
= do = do
...@@ -1743,6 +1754,10 @@ linkDynLib dflags0 o_files dep_packages ...@@ -1743,6 +1754,10 @@ linkDynLib dflags0 o_files dep_packages
++ [ Option "-o" ++ [ Option "-o"
, FileOption "" output_fn , FileOption "" output_fn
] ]
-- See Note [No PIE eating when linking]
++ (if sGccSupportsNoPie (settings dflags)
then [Option "-no-pie"]
else [])
++ map Option o_files ++ map Option o_files
++ [ Option "-shared" ] ++ [ Option "-shared" ]
++ map Option bsymbolicFlag ++ map Option bsymbolicFlag
......
...@@ -647,6 +647,9 @@ dnl If gcc, make sure it's at least 3.0 ...@@ -647,6 +647,9 @@ dnl If gcc, make sure it's at least 3.0
dnl dnl
FP_GCC_VERSION 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 ** look to see if we have a C compiler using an llvm back end.
dnl dnl
FP_CC_LLVM_BACKEND FP_CC_LLVM_BACKEND
......
...@@ -92,6 +92,7 @@ FIND_LD([LdCmd]) ...@@ -92,6 +92,7 @@ FIND_LD([LdCmd])
AC_SUBST([LdCmd]) AC_SUBST([LdCmd])
FP_GCC_VERSION FP_GCC_VERSION
FP_GCC_SUPPORTS_NO_PIE
AC_PROG_CPP AC_PROG_CPP
FP_PROG_LD_IS_GNU FP_PROG_LD_IS_GNU
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
("C compiler command", "@SettingsCCompilerCommand@"), ("C compiler command", "@SettingsCCompilerCommand@"),
("C compiler flags", "@SettingsCCompilerFlags@"), ("C compiler flags", "@SettingsCCompilerFlags@"),
("C compiler link flags", "@SettingsCCompilerLinkFlags@"), ("C compiler link flags", "@SettingsCCompilerLinkFlags@"),
("C compiler supports -no-pie", "@SettingsCCompilerSupportsNoPie@"),
("Haskell CPP command","@SettingsHaskellCPPCommand@"), ("Haskell CPP command","@SettingsHaskellCPPCommand@"),
("Haskell CPP flags","@SettingsHaskellCPPFlags@"), ("Haskell CPP flags","@SettingsHaskellCPPFlags@"),
("ld command", "@SettingsLdCommand@"), ("ld command", "@SettingsLdCommand@"),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment