Commit 1b7f5976 authored by Peter Trommler's avatar Peter Trommler 🥁 Committed by Herbert Valerio Riedel
Browse files

Link temporary shared objects with `--no-as-needed`

Some ELF link editors default to `--as-needed` and record only
those libraries in DT_NEEDED tags that are needed to resolve
undefined symbols in the shared object to be created.

In Template Haskell we rely on all symbols that were defined
in modules compiled so far to be available in the current
temporary shared object. To prevent the link editor from
dropping the DT_NEEDED tag for the previously linked temporary
shared object we need to override the link editors default and
specify `--no-as-needed` on the command line. This is for GNU ld
and GOLD ld.

This addresses #10110

TODO: regression test

Reviewed By: hvr

Differential Revision: https://phabricator.haskell.org/D731
parent cc07a0ba
......@@ -690,7 +690,7 @@ in terror).
{- Note [Run-time linker info]
See also: Trac #5240, Trac #6063
See also: Trac #5240, Trac #6063, Trac #10110
Before 'runLink', we need to be sure to get the relevant information
about the linker we're using at runtime to see if we need any extra
......@@ -717,6 +717,13 @@ We cache the LinkerInfo inside DynFlags, since clients may link
multiple times. The definition of LinkerInfo is there to avoid a
circular dependency.
Some distributions change the link editor's default handling of
ELF DT_NEEDED tags to include only those shared objects that are
needed to resolve undefined symbols. For Template Haskell we need
the last temporary shared library also if it is not needed for the
currently linked temporary shared library. We specify --no-as-needed
to override the default. This flag exists in GNU ld and GNU gold.
-}
......@@ -753,12 +760,14 @@ getLinkerInfo' dflags = do
| any ("GNU ld" `isPrefixOf`) stdo =
-- GNU ld specifically needs to use less memory. This especially
-- hurts on small object files. Trac #5240.
-- Set DT_NEEDED for all shared libraries. Trac #10110.
return (GnuLD $ map Option ["-Wl,--hash-size=31",
"-Wl,--reduce-memory-overheads"])
"-Wl,--reduce-memory-overheads",
"-Wl,--no-as-needed"])
| any ("GNU gold" `isPrefixOf`) stdo =
-- GNU gold does not require any special arguments.
return (GnuGold [])
-- GNU gold only needs --no-as-needed. Trac #10110.
return (GnuGold [Option "-Wl,--no-as-needed"])
-- Unknown linker.
| otherwise = fail "invalid --version output, or linker is unsupported"
......@@ -875,7 +884,7 @@ runLink dflags args = do
linkargs <- neededLinkArgs `fmap` getLinkerInfo dflags
let (p,args0) = pgm_l dflags
args1 = map Option (getOpts dflags opt_l)
args2 = args0 ++ args1 ++ args ++ linkargs
args2 = args0 ++ linkargs ++ args1 ++ args
mb_env <- getGccEnv args2
runSomethingFiltered dflags ld_filter "Linker" p args2 mb_env
where
......
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