[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