summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-02-26 14:27:47 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-02-26 14:27:47 +0000
commit993f0273e3998f8b15a52a2feade074917d20113 (patch)
treecb6a4b04b6408328fda66cd53478ca4d83fe2742 /lld/ELF/OutputSections.cpp
parent31d315b349947ce4c46bb348776480c658876793 (diff)
downloadbcm5719-llvm-993f0273e3998f8b15a52a2feade074917d20113.tar.gz
bcm5719-llvm-993f0273e3998f8b15a52a2feade074917d20113.zip
Fix some confusion about what can be preempted.
For shared libraries we allow any weak undefined symbol to eventually be resolved, even if we never see a definition in another .so. This matches the behavior when handling other undefined symbols in a shared library. For executables, we require seeing a definition in a .so or resolve it to zero. This is also similar to how non weak symbols are handled. llvm-svn: 262017
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp32
1 files changed, 10 insertions, 22 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 384f02acef3..5ed7cc0337a 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -176,7 +176,7 @@ template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
// As the first approach, we can just store addresses for all symbols.
- if (Config->EMachine != EM_MIPS && canBePreempted(B, false))
+ if (Config->EMachine != EM_MIPS && canBePreempted(B))
continue; // The dynamic linker will take care of it.
uintX_t VA = B->getVA<ELFT>();
write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
@@ -926,7 +926,7 @@ elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
// Returns true if a symbol can be replaced at load-time by a symbol
// with the same name defined in other ELF executable or DSO.
-bool elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) {
+bool elf2::canBePreempted(const SymbolBody *Body) {
if (!Body)
return false; // Body is a local symbol.
if (Body->isShared())
@@ -936,26 +936,14 @@ bool elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) {
if (!Body->isWeak())
return true;
- // This is an horrible corner case. Ideally we would like to say that any
- // undefined symbol can be preempted so that the dynamic linker has a
- // chance of finding it at runtime.
- //
- // The problem is that the code sequence used to test for weak undef
- // functions looks like
- // if (func) func()
- // If the code is -fPIC the first reference is a load from the got and
- // everything works.
- // If the code is not -fPIC there is no reasonable way to solve it:
- // * A relocation writing to the text segment will fail (it is ro).
- // * A copy relocation doesn't work for functions.
- // * The trick of using a plt entry as the address would fail here since
- // the plt entry would have a non zero address.
- // Since we cannot do anything better, we just resolve the symbol to 0 and
- // don't produce a dynamic relocation.
- //
- // As an extra hack, assume that if we are producing a shared library the
- // user knows what he or she is doing and can handle a dynamic relocation.
- return Config->Shared || NeedsGot;
+ // Ideally the static linker should see a definition for every symbol, but
+ // shared object are normally allowed to have undefined references that the
+ // static linker never sees a definition for.
+ if (Config->Shared)
+ return true;
+
+ // Otherwise, just resolve to 0.
+ return false;
}
if (!Config->Shared)
return false;
OpenPOWER on IntegriCloud