summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2019-07-16 11:37:55 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-11-11 07:22:39 -0500
commitaf653b5f8e1d81eeb28ecf730d41e4c83fe76241 (patch)
treea1f8a46d0e91b3ed3bf6a0a9c74322d053e05589
parent4230e4fb8c12da16ad994a9af6b81ff755084bc6 (diff)
downloadhaskell-af653b5f8e1d81eeb28ecf730d41e4c83fe76241.tar.gz
Only pass -pie, -no-pie when linking
Previously, these flags were passed when both compiling and linking code. However, `-pie` and `-no-pie` are link-time-only options. Usually, this does not cause issues, but when using Clang with `-Werror` set results in errors: clang: error: argument unused during compilation: '-nopie' [-Werror,-Wunused-command-line-argument] This is unused by Clang because this flag has no effect at compile time (it’s called `-nopie` internally by Clang but called `-no-pie` in GHC for compatibility with GCC). Just passing these flags at linking time resolves this. Additionally, update #15319 hack to look for `-pgml` instead. Because of the main change, the value of `-pgmc` does not matter when checking for the workaround of #15319. However, `-pgml` *does* still matter as not all `-pgml` values support `-no-pie`. To cover all potential values, we assume that no custom `-pgml` values support `-no-pie`. This means that we run the risk of not using `-no-pie` when it is otherwise necessary for in auto-hardened toolchains! This could be a problem at some point, but this workaround was already introduced in 8d008b71 and we might as well continue supporting it. Likewise, mark `-pgmc-supports-no-pie` as deprecated and create a new `-pgml-supports-no-pie`.
-rw-r--r--compiler/GHC/Driver/Session.hs36
-rw-r--r--compiler/GHC/Linker/Static.hs2
-rw-r--r--docs/users_guide/phases.rst18
3 files changed, 38 insertions, 18 deletions
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 5d194d2d58..b4983d9218 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -177,6 +177,9 @@ module GHC.Driver.Session (
-- ** DynFlags C compiler options
picCCOpts, picPOpts,
+ -- ** DynFlags C linker options
+ pieCCLDOpts,
+
-- * Compiler configuration suitable for display to the user
compilerInfo,
@@ -2060,20 +2063,28 @@ dynamic_flags_deps = [
, make_ord_flag defFlag "pgmF"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_F = f }
, make_ord_flag defFlag "pgmc"
- $ hasArg $ \f -> alterToolSettings $ \s -> s
- { toolSettings_pgm_c = f
- , -- Don't pass -no-pie with -pgmc
- -- (see #15319)
- toolSettings_ccSupportsNoPie = False
- }
- , make_ord_flag defFlag "pgmc-supports-no-pie"
- $ noArg $ alterToolSettings $ \s -> s { toolSettings_ccSupportsNoPie = True }
+ $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_c = f }
+ , (Deprecated, defFlag "pgmc-supports-no-pie"
+ $ noArgM $ \d -> do
+ deprecate $ "use -pgml-supports-no-pie instead"
+ pure $ alterToolSettings (\s -> s { toolSettings_ccSupportsNoPie = True }) d)
, make_ord_flag defFlag "pgms"
(HasArg (\_ -> addWarn "Object splitting was removed in GHC 8.8"))
, make_ord_flag defFlag "pgma"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_a = (f,[]) }
, make_ord_flag defFlag "pgml"
- $ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_l = (f,[]) }
+ $ hasArg $ \f -> alterToolSettings $ \s -> s
+ { toolSettings_pgm_l = (f,[])
+ , -- Don't pass -no-pie with custom -pgml (see #15319). Note
+ -- that this could break when -no-pie is actually needed.
+ -- But the CC_SUPPORTS_NO_PIE check only happens at
+ -- buildtime, and -pgml is a runtime option. A better
+ -- solution would be running this check for each custom
+ -- -pgml.
+ toolSettings_ccSupportsNoPie = False
+ }
+ , make_ord_flag defFlag "pgml-supports-no-pie"
+ $ noArg $ alterToolSettings $ \s -> s { toolSettings_ccSupportsNoPie = True }
, make_ord_flag defFlag "pgmdll"
$ hasArg $ \f -> alterToolSettings $ \s -> s { toolSettings_pgm_dll = (f,[]) }
, make_ord_flag defFlag "pgmwindres"
@@ -4414,9 +4425,7 @@ setOptHpcDir arg = upd $ \ d -> d {hpcDir = arg}
-- platform.
picCCOpts :: DynFlags -> [String]
-picCCOpts dflags = pieOpts ++ picOpts
- where
- picOpts =
+picCCOpts dflags =
case platformOS (targetPlatform dflags) of
OSDarwin
-- Apple prefers to do things the other way round.
@@ -4444,7 +4453,8 @@ picCCOpts dflags = pieOpts ++ picOpts
-- explicit here, see #15847
| otherwise -> ["-fno-PIC"]
- pieOpts
+pieCCLDOpts :: DynFlags -> [String]
+pieCCLDOpts dflags
| gopt Opt_PICExecutable dflags = ["-pie"]
-- See Note [No PIE when linking]
| toolSettings_ccSupportsNoPie (toolSettings dflags) = ["-no-pie"]
diff --git a/compiler/GHC/Linker/Static.hs b/compiler/GHC/Linker/Static.hs
index d5e9147509..108dbec525 100644
--- a/compiler/GHC/Linker/Static.hs
+++ b/compiler/GHC/Linker/Static.hs
@@ -202,7 +202,7 @@ linkBinary' staticLink logger tmpfs dflags unit_env o_files dep_units = do
[]
-- See Note [No PIE when linking]
- ++ picCCOpts dflags
+ ++ pieCCLDOpts dflags
-- Permit the linker to auto link _symbol to _imp_symbol.
-- This lets us link against DLLs without needing an "import library".
diff --git a/docs/users_guide/phases.rst b/docs/users_guide/phases.rst
index 0c334f037f..8b99939d98 100644
--- a/docs/users_guide/phases.rst
+++ b/docs/users_guide/phases.rst
@@ -181,14 +181,24 @@ the following flags:
Pass ⟨option⟩ to the C compiler.
.. ghc-flag:: -pgmc-supports-no-pie
- :shortdesc: Indicate that the C compiler supports ``-no-pie``
+ :shortdesc: *(deprecated)*
+ Indicate that the linker supports ``-no-pie``
:type: dynamic
:category: phase-options
- When ``-pgmc`` is used, GHC by default will never pass the ``-no-pie``
+ Does the same thing as ``-pgml-supports-no-pie``, which replaced it.
+
+.. ghc-flag:: -pgml-supports-no-pie
+ :shortdesc: Indicate that the linker supports ``-no-pie``
+ :type: dynamic
+ :category: phase-options
+
+ When ``-pgml`` is used, GHC by default will never pass the ``-no-pie``
command line flag. The rationale is that it is not known whether the
- specified compiler will support it. This flag can be used to indicate
- that ``-no-pie`` is supported. It has to be passed after ``-pgmc``.
+ specified compiler used for linking (recall we use a C compiler to
+ invoke the linker on our behalf) will support it. This flag can be
+ used to indicate that ``-no-pie`` is supported. It has to be passed
+ after ``-pgml``.
This flag is not necessary when ``-pgmc`` is not used, since GHC
remembers whether the default C compiler supports ``-no-pie`` in