diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-01-06 22:30:35 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-01-06 22:30:35 +0000 |
commit | 2756e04fac8eae63c8c7782ff14481637808de80 (patch) | |
tree | 262136fedd399dc540e85762b60fb043317b5a3b /lld/ELF/InputFiles.cpp | |
parent | 5a2f078ee2612908140e8df05de85c8a7322fe9d (diff) | |
download | bcm5719-llvm-2756e04fac8eae63c8c7782ff14481637808de80.tar.gz bcm5719-llvm-2756e04fac8eae63c8c7782ff14481637808de80.zip |
Handle versioned undefined symbols.
In order to keep symbol lookup a simple name lookup this patch adds
versioned symbols with an explicit @ to the symbol table.
llvm-svn: 291293
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
-rw-r--r-- | lld/ELF/InputFiles.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index bd9f25873c8..abe90445b6b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -651,6 +651,8 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { VersymIndex = Versym->vs_index; ++Versym; } + bool Hidden = VersymIndex & VERSYM_HIDDEN; + VersymIndex = VersymIndex & ~VERSYM_HIDDEN; StringRef Name = check(Sym.getName(this->StringTable)); if (Sym.isUndefined()) { @@ -658,15 +660,23 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() { continue; } - if (Versym) { - // Ignore local symbols and non-default versions. - if (VersymIndex == VER_NDX_LOCAL || (VersymIndex & VERSYM_HIDDEN)) - continue; - } + // Ignore local symbols. + if (Versym && VersymIndex == VER_NDX_LOCAL) + continue; const Elf_Verdef *V = VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex]; - elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); + + if (!Hidden) + elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); + + // Also add the symbol with the versioned name to handle undefined symbols + // with explicit versions. + if (V) { + StringRef VerName = this->StringTable.data() + V->getAux()->vda_name; + Name = Saver.save(Twine(Name) + "@" + VerName); + elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V); + } } } |