Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/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,24 @@ if (Backref && !isWeak()) warn("backward reference detected: " + Other.getName() + " in " + toString(Other.File) + " refers to " + toString(File)); + return; + } + + // Undefined symbols in a SharedFile do not change the binding. + if (dyn_cast_or_null(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: lld/trunk/test/ELF/archive-fetch.s =================================================================== --- lld/trunk/test/ELF/archive-fetch.s +++ lld/trunk/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: lld/trunk/test/ELF/weak-undef-shared.s =================================================================== --- lld/trunk/test/ELF/weak-undef-shared.s +++ lld/trunk/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