Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -410,18 +410,7 @@ if (Traced) printTraceSymbol(&Other); - if (isUndefined()) { - // The binding may "upgrade" from weak to non-weak. - if (Other.Binding != STB_WEAK) - Binding = Other.Binding; - } else if (auto *S = dyn_cast(this)) { - // The binding of a SharedSymbol will be weak if there is at least one - // reference and all are weak. The binding has one opportunity to change to - // weak: if the first reference is weak. - if (Other.Binding != STB_WEAK || !S->Referenced) - Binding = Other.Binding; - S->Referenced = true; - } else if (isLazy()) { + if (isLazy()) { // An undefined weak will not fetch archive members. See comment on Lazy in // Symbols.h for the details. if (Other.Binding == STB_WEAK) { @@ -489,6 +478,23 @@ if (Backref && !isWeak()) warn("backward reference detected: " + Other.getName() + " in " + toString(Other.File) + " refers to " + toString(File)); + } else { + // Undefined symbols in a SharedFile do not change the binding. + if (isa_and_nonnull(Other.File)) + return; + + if (isUndefined()) { + // The binding may "upgrade" from weak to non-weak. + if (Other.Binding != STB_WEAK) + Binding = Other.Binding; + } else if (auto *S = dyn_cast(this)) { + // The binding of a SharedSymbol will be weak if there is at least one + // reference and all are weak. The binding has one opportunity to change + // to weak: if the first reference is weak. + if (Other.Binding != STB_WEAK || !S->Referenced) + Binding = Other.Binding; + S->Referenced = true; + } } } Index: test/ELF/archive-fetch.s =================================================================== --- test/ELF/archive-fetch.s +++ test/ELF/archive-fetch.s @@ -9,7 +9,14 @@ # RUN: llvm-ar rcs %t.a %tfoo.o %tbar.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld %t.a %t.o -o /dev/null +# RUN: ld.lld %t.a %t.o -o %t +# RUN: llvm-nm %t | FileCheck %s + +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: ld.lld %t.a %t.so -o %t +# RUN: llvm-nm %t | FileCheck %s + +# CHECK: T foo _start: callq foo Index: test/ELF/weak-undef-shared.s =================================================================== --- test/ELF/weak-undef-shared.s +++ test/ELF/weak-undef-shared.s @@ -24,6 +24,11 @@ # RUN: ld.lld %t2.o %t.so %t1.o -o %t # RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=GLOBAL %s +## Check the binding (weak) is not affected by the STB_GLOBAL undefined +## reference in %t2.so +# RUN: ld.lld %t1.o %t2.so -o %t +# RUN: llvm-readelf --dyn-syms %t | FileCheck --check-prefix=WEAK %s + # WEAK: NOTYPE WEAK DEFAULT UND foo # GLOBAL: NOTYPE GLOBAL DEFAULT UND foo