ELF: Override DSO definitions when creating __start_* and __stop_* symbols.
authorPeter Collingbourne <peter@pcc.me.uk>
Thu, 13 Oct 2016 22:20:18 +0000 (22:20 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Thu, 13 Oct 2016 22:20:18 +0000 (22:20 +0000)
commit24a01c341e5bcbe9389c3a482b08a58063b06115
tree016a93efe752143ff96ac21c42d578c16236ebe0
parent4f606296a500f61e774e2c823074c79db34ae852
ELF: Override DSO definitions when creating __start_* and __stop_* symbols.

Previously we would fail to synthesise a __start_ or __stop_ symbol if
there existed a definition in a DSO. Instead, we would try to link against
the DSO definition. This became possible after D23552 when linking against
lld-produced DSOs but could in principle also occur when linking against
DSOs produced by other linkers.

Not only does it seem more likely that a user would expect the resolved
definition to be local to the executable, but if a __start_ or __stop_
symbol was synthesised by the linker, it is effectively impossible to link
against correctly from a non-PIC executable in a read-only section. Neither
a PLT nor a copy relocation would give us the right semantics here. The only
way the link could succeed is if the executable provided its own synthetic
definition of the symbol.

The fix is to also synthesise the definition if the only definition comes
from a DSO. Since this is what the addOptionalSynthetic function does,
switch to using that function.

Fixes PR30680.

Differential Revision: https://reviews.llvm.org/D25544

llvm-svn: 284168
lld/ELF/Writer.cpp
lld/test/ELF/Inputs/startstop-shared2.s [new file with mode: 0644]
lld/test/ELF/startstop-shared2.s [new file with mode: 0644]