Commit d421a7e2 authored by Ben Gamari's avatar Ben Gamari Committed by Ben Gamari

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 ec0bf811
......@@ -509,12 +509,14 @@ AC_DEFUN([FP_SETTINGS],
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)
......@@ -1322,6 +1324,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
......
......@@ -1859,6 +1859,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
......@@ -2157,6 +2162,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"])
......
......@@ -955,6 +955,7 @@ data Settings = Settings {
sLdSupportsBuildId :: Bool,
sLdSupportsFilelist :: Bool,
sLdIsGnuLd :: Bool,
sGccSupportsNoPie :: Bool,
-- commands for particular phases
sPgm_L :: String,
sPgm_P :: (String,[Option]),
......
......@@ -251,6 +251,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
......@@ -343,6 +344,7 @@ initSysTools mbMinusB
sLdSupportsBuildId = ldSupportsBuildId,
sLdSupportsFilelist = ldSupportsFilelist,
sLdIsGnuLd = ldIsGnuLd,
sGccSupportsNoPie = gccSupportsNoPie,
sProgramName = "ghc",
sProjectVersion = cProjectVersion,
sPgm_L = unlit_path,
......@@ -1546,6 +1548,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 +1722,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
......
......@@ -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
......
......@@ -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
......
......@@ -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@"),
......
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