[PATCH] D107535: [ELF] Support copy relocation on non-default version symbols
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 5 10:14:16 PDT 2021
MaskRay added a comment.
Thanks!
> IIUC if we were to fix the alias problem then we'd need to load the versym section and get the version info for each alias candidate so that we'd do find("sym at ver") rather than ("sym").
Yes. I have actually implemented it but realized that it is an overkill.
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index d5b9efbe18fc..e3cc3821ffad 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1608,6 +1608,9 @@ template <class ELFT> void SharedFile::parse() {
sym.st_other, sym.getType(), sym.st_value,
sym.st_size, alignment, idx});
}
+
+ if (versymSec)
+ this->versyms = std::move(versyms);
}
static ELFKind getBitcodeELFKind(const Triple &t) {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index bd72cfcdd050..bc01ad31e1cd 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -367,6 +367,8 @@ public:
// This is actually a vector of Elf_Verdef pointers.
std::vector<const void *> verdefs;
+ std::vector<uint16_t> versyms;
+
// If the output file needs Elf_Verneed data structures for this file, this is
// a vector of Elf_Vernaux version identifiers that map onto the entries in
// Verdefs, otherwise it is empty.
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index e3cc210972b2..778b2086581a 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -516,13 +516,27 @@ static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &ss) {
using Elf_Sym = typename ELFT::Sym;
SharedFile &file = ss.getFile();
-
+ SmallString<128> buf;
SmallSet<SharedSymbol *, 4> ret;
- for (const Elf_Sym &s : file.template getGlobalELFSyms<ELFT>()) {
+ for (auto it : enumerate(file.template getGlobalELFSyms<ELFT>())) {
+ const Elf_Sym &s = it.value();
if (s.st_shndx == SHN_UNDEF || s.st_shndx == SHN_ABS ||
s.getType() == STT_TLS || s.st_value != ss.value)
continue;
StringRef name = check(s.getName(file.getStringTable()));
+ // Append @ suffix if the symbol has a non-default version.
+ const uint16_t idx =
+ file.versyms.empty() ? VER_NDX_GLOBAL : file.versyms[it.index()];
+ if ((idx & VERSYM_HIDDEN) && (idx & ~VERSYM_HIDDEN) > VER_NDX_GLOBAL) {
+ StringRef verName = file.getStringTable().data() +
+ reinterpret_cast<const typename ELFT::Verdef *>(
+ file.verdefs[idx & ~VERSYM_HIDDEN])
+ ->getAux()
+ ->vda_name;
+ buf.clear();
+ name = (name + "@" + verName).toStringRef(buf);
+ }
+
Symbol *sym = symtab->find(name);
if (auto *alias = dyn_cast_or_null<SharedSymbol>(sym))
ret.insert(alias);
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D107535/new/
https://reviews.llvm.org/D107535
More information about the llvm-commits
mailing list