diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1838,12 +1838,15 @@ llvm::TimeTraceScope timeScope("Demote shared symbols"); for (Symbol *sym : symtab->symbols()) { auto *s = dyn_cast(sym); - if (!s || s->getFile().isNeeded) + if (!((s && !s->getFile().isNeeded) || + (sym->isLazy() && sym->isUsedInRegularObj))) continue; - bool used = s->used; - s->replace(Undefined{nullptr, s->getName(), STB_WEAK, s->stOther, s->type}); - s->used = used; + bool used = sym->used; + sym->replace( + Undefined{nullptr, sym->getName(), STB_WEAK, sym->stOther, sym->type}); + sym->used = used; + sym->versionId = VER_NDX_GLOBAL; } } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -163,10 +163,7 @@ // True if this is an undefined weak symbol. This only works once // all input files have been added. - bool isUndefWeak() const { - // See comment on lazy symbols for details. - return isWeak() && (isUndefined() || isLazy()); - } + bool isUndefWeak() const { return isWeak() && isUndefined(); } StringRef getName() const { if (nameSize == (uint32_t)-1) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3161,10 +3161,10 @@ void VersionTableSection::writeTo(uint8_t *buf) { buf += 2; for (const SymbolTableEntry &s : getPartition().dynSymTab->getSymbols()) { - // Use the original versionId for an unfetched lazy symbol (undefined weak), - // which must be VER_NDX_GLOBAL (an undefined versioned symbol is an error). - write16(buf, s.sym->isLazy() ? static_cast(VER_NDX_GLOBAL) - : s.sym->versionId); + // For an unfetched lazy symbol (undefined weak), it must have been + // converted to Undefined and have VER_NDX_GLOBAL version here. + assert(!s.sym->isLazy()); + write16(buf, s.sym->versionId); buf += 2; } }