diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 8c7f2c8773f2c..4b4d7d6db93cd 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1546,7 +1546,7 @@ template void SharedFile::parse() { SharedSymbol{*this, name, sym.getBinding(), sym.st_other, sym.getType(), sym.st_value, sym.st_size, alignment}); if (s->file == this) - s->verdefIndex = ver; + s->versionId = ver; } // Also add the symbol with the versioned name to handle undefined symbols @@ -1563,7 +1563,7 @@ template void SharedFile::parse() { SharedSymbol{*this, saver().save(name), sym.getBinding(), sym.st_other, sym.getType(), sym.st_value, sym.st_size, alignment}); if (s->file == this) - s->verdefIndex = idx; + s->versionId = idx; } } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 6765461805dad..d4685ce70ece8 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -309,7 +309,6 @@ static void replaceWithDefined(Symbol &sym, SectionBase &sec, uint64_t value, size, &sec) .overwrite(sym); - sym.verdefIndex = old.verdefIndex; sym.exportDynamic = true; sym.isUsedInRegularObj = true; // A copy relocated alias may need a GOT entry. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index fe7edd5b0eb49..b3d97e4de7790 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -92,7 +92,6 @@ Symbol *SymbolTable::insert(StringRef name) { memset(sym, 0, sizeof(Symbol)); sym->setName(name); sym->partition = 1; - sym->verdefIndex = -1; sym->versionId = VER_NDX_GLOBAL; if (pos != StringRef::npos) sym->hasVersionSuffix = true; @@ -235,10 +234,9 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId, sym->getName().contains('@')) continue; - // If the version has not been assigned, verdefIndex is -1. Use an arbitrary - // number (0) to indicate the version has been assigned. - if (sym->verdefIndex == uint16_t(-1)) { - sym->verdefIndex = 0; + // If the version has not been assigned, assign versionId to the symbol. + if (!sym->versionScriptAssigned) { + sym->versionScriptAssigned = true; sym->versionId = versionId; } if (sym->versionId == versionId) @@ -256,8 +254,8 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId, // so we set a version to a symbol only if no version has been assigned // to the symbol. This behavior is compatible with GNU. for (Symbol *sym : findAllByVersion(ver, includeNonDefault)) - if (sym->verdefIndex == uint16_t(-1)) { - sym->verdefIndex = 0; + if (!sym->versionScriptAssigned) { + sym->versionScriptAssigned = true; sym->versionId = versionId; } } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 4addb79d12579..0c79efccb5486 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -313,11 +313,12 @@ class Symbol { uint32_t auxIdx; uint32_t dynsymIndex; - // This field is a index to the symbol's version definition. - uint16_t verdefIndex; - - // Version definition index. + // For a Defined symbol, this represents the Verdef index (VER_NDX_LOCAL, + // VER_NDX_GLOBAL, or a named version). For a SharedSymbol, this represents + // the Verdef index within the input DSO, which will be converted to a Verneed + // index in the output. uint16_t versionId; + uint8_t versionScriptAssigned : 1; void setFlags(uint16_t bits) { flags.fetch_or(bits, std::memory_order_relaxed); @@ -357,7 +358,6 @@ class Defined : public Symbol { } void overwrite(Symbol &sym) const { Symbol::overwrite(sym, DefinedKind); - sym.verdefIndex = -1; auto &s = static_cast(sym); s.value = value; s.size = size; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 0f7ebf9d7ba84..2b32eb3a0fe35 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3140,10 +3140,8 @@ bool VersionTableSection::isNeeded() const { void elf::addVerneed(Symbol *ss) { auto &file = cast(*ss->file); - if (ss->verdefIndex == VER_NDX_GLOBAL) { - ss->versionId = VER_NDX_GLOBAL; + if (ss->versionId == VER_NDX_GLOBAL) return; - } if (file.vernauxs.empty()) file.vernauxs.resize(file.verdefs.size()); @@ -3152,10 +3150,10 @@ void elf::addVerneed(Symbol *ss) { // already allocated one. The verdef identifiers cover the range // [1..getVerDefNum()]; this causes the vernaux identifiers to start from // getVerDefNum()+1. - if (file.vernauxs[ss->verdefIndex] == 0) - file.vernauxs[ss->verdefIndex] = ++SharedFile::vernauxNum + getVerDefNum(); + if (file.vernauxs[ss->versionId] == 0) + file.vernauxs[ss->versionId] = ++SharedFile::vernauxNum + getVerDefNum(); - ss->versionId = file.vernauxs[ss->verdefIndex]; + ss->versionId = file.vernauxs[ss->versionId]; } template