Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1119,19 +1119,27 @@ Symtab->fetchLazy(Sym); } -// If all references to a DSO happen to be weak, the DSO is not added -// to DT_NEEDED. If that happens, we need to eliminate shared symbols -// created from the DSO. Otherwise, they become dangling references -// that point to a non-existent DSO. -template static void demoteSharedSymbols() { +template static bool shouldDemote(Symbol &Sym) { + // If all references to a DSO happen to be weak, the DSO is not added to + // DT_NEEDED. If that happens, we need to eliminate shared symbols created + // from the DSO. Otherwise, they become dangling references that point to a + // non-existent DSO. + if (auto *S = dyn_cast(&Sym)) + return !S->getFile().IsNeeded; + + // We are done processing archives, so lazy symbols that were used but not + // found can be converted to undefined. We could also just delete the other + // lazy symbols, but that seems to be more work than it is worth. + return Sym.isLazy() && Sym.IsUsedInRegularObj; +} + +template static void demoteSymbols() { for (Symbol *Sym : Symtab->getSymbols()) { - if (auto *S = dyn_cast(Sym)) { - if (!S->getFile().IsNeeded) { - bool Used = S->Used; - replaceSymbol(S, nullptr, S->getName(), STB_WEAK, S->StOther, - S->Type); - S->Used = Used; - } + if (shouldDemote(*Sym)) { + bool Used = Sym->Used; + replaceSymbol(Sym, nullptr, Sym->getName(), Sym->Binding, + Sym->StOther, Sym->Type); + Sym->Used = Used; } } } @@ -1296,7 +1304,7 @@ // Do size optimizations: garbage collection, merging of SHF_MERGE sections // and identical code folding. markLive(); - demoteSharedSymbols(); + demoteSymbols(); decompressSections(); mergeSections(); if (Config->ICF) Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -95,12 +95,8 @@ return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; } - // 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()); - } + // True if this is an undefined weak symbol. + bool isUndefWeak() const { return isWeak() && isUndefined(); } StringRef getName() const { return Name; } void parseSymbolVersion(); Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -109,8 +109,7 @@ return 0; case Symbol::LazyArchiveKind: case Symbol::LazyObjectKind: - assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer"); - return 0; + llvm_unreachable("lazy symbol reached writer"); } llvm_unreachable("invalid symbol kind"); }