Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -292,6 +292,7 @@ const Elf_Shdr *VerdefSec = nullptr; public: + std::vector Verdefs; std::string SoName; llvm::ArrayRef getUndefinedSymbols() { return Undefs; } Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -794,7 +794,7 @@ template void SharedFile::parseRest() { // Create mapping from version identifiers to Elf_Verdef entries. const Elf_Versym *Versym = nullptr; - std::vector Verdefs = parseVerdefs(Versym); + Verdefs = parseVerdefs(Versym); ArrayRef Sections = CHECK(this->getObj().sections(), this); @@ -827,6 +827,8 @@ continue; } Ver = Verdefs[VersymIndex]; + } else { + VersymIndex = 0; } // We do not usually care about alignments of data in shared object @@ -844,14 +846,14 @@ error(toString(this) + ": alignment too large: " + Name); if (!Hidden) - Symtab->addShared(Name, this, Sym, Alignment, Ver); + Symtab->addShared(Name, this, Sym, Alignment, VersymIndex); // Also add the symbol with the versioned name to handle undefined symbols // with explicit versions. if (Ver) { StringRef VerName = this->StringTable.data() + Ver->getAux()->vda_name; Name = Saver.save(Name + "@" + VerName); - Symtab->addShared(Name, this, Sym, Alignment, Ver); + Symtab->addShared(Name, this, Sym, Alignment, VersymIndex); } } } Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -59,7 +59,7 @@ template void addShared(StringRef Name, SharedFile *F, const typename ELFT::Sym &Sym, uint32_t Alignment, - const typename ELFT::Verdef *Verdef); + uint32_t VerdefIndex); template Symbol *addLazyArchive(StringRef Name, ArchiveFile *F, Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -478,7 +478,7 @@ template void SymbolTable::addShared(StringRef Name, SharedFile *File, const typename ELFT::Sym &Sym, uint32_t Alignment, - const typename ELFT::Verdef *Verdef) { + uint32_t VerdefIndex) { // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT // as the visibility, which will leave the visibility in the symbol table // unchanged. @@ -497,7 +497,7 @@ uint8_t Binding = S->Binding; replaceSymbol(S, File, Name, Sym.getBinding(), Sym.st_other, Sym.getType(), Sym.st_value, Sym.st_size, - Alignment, Verdef); + Alignment, VerdefIndex); if (!WasInserted) { S->Binding = Binding; if (!S->isWeak() && !Config->GcSections) @@ -839,20 +839,16 @@ template void SymbolTable::addShared(StringRef, SharedFile *, const typename ELF32LE::Sym &, - uint32_t Alignment, - const typename ELF32LE::Verdef *); + uint32_t Alignment, uint32_t); template void SymbolTable::addShared(StringRef, SharedFile *, const typename ELF32BE::Sym &, - uint32_t Alignment, - const typename ELF32BE::Verdef *); + uint32_t Alignment, uint32_t); template void SymbolTable::addShared(StringRef, SharedFile *, const typename ELF64LE::Sym &, - uint32_t Alignment, - const typename ELF64LE::Verdef *); + uint32_t Alignment, uint32_t); template void SymbolTable::addShared(StringRef, SharedFile *, const typename ELF64BE::Sym &, - uint32_t Alignment, - const typename ELF64BE::Verdef *); + uint32_t Alignment, uint32_t); template void SymbolTable::fetchIfLazy(StringRef); template void SymbolTable::fetchIfLazy(StringRef); Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -210,9 +210,9 @@ SharedSymbol(InputFile *File, StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, - uint32_t Alignment, const void *Verdef) - : Symbol(SharedKind, File, Name, Binding, StOther, Type), Verdef(Verdef), - Value(Value), Size(Size), Alignment(Alignment) { + uint32_t Alignment, uint32_t VerdefIndex) + : Symbol(SharedKind, File, Name, Binding, StOther, Type), Value(Value), + Size(Size), VerdefIndex(VerdefIndex), Alignment(Alignment) { // GNU ifunc is a mechanism to allow user-supplied functions to // resolve PLT slot values at load-time. This is contrary to the // regualr symbol resolution scheme in which symbols are resolved just @@ -237,14 +237,15 @@ return cast>(File); } - // This field is a pointer to the symbol's version definition. - const void *Verdef; - // If not null, there is a copy relocation to this section. InputSection *CopyRelSec = nullptr; uint64_t Value; // st_value uint64_t Size; // st_size + + // This field is a index to the symbol's version definition. + uint32_t VerdefIndex; + uint32_t Alignment; }; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2305,14 +2305,13 @@ template void VersionNeedSection::addSymbol(SharedSymbol *SS) { - auto *Ver = reinterpret_cast(SS->Verdef); + SharedFile *File = SS->getFile(); + const typename ELFT::Verdef *Ver = File->Verdefs[SS->VerdefIndex]; if (!Ver) { SS->VersionId = VER_NDX_GLOBAL; return; } - SharedFile *File = SS->getFile(); - // If we don't already know that we need an Elf_Verneed for this DSO, prepare // to create one by adding it to our needed list and creating a dynstr entry // for the soname.