[ELF] Don't change binding to STB_WEAK for an undefined specified by -u

Similar to D66992.
In GNU ld, a -u specified symbol is a STB_DEFAULT undefined.
It cannot be changed to STB_WEAK by a later STB_WEAK undefined in a regular object file.

The behavior is consistent with our model because -u means "we need to fetch a lazy definition".
It should not be altered just because there is also a STB_WEAK undefined.

Note, our -u semantics are still different from GNU ld (https://github.com/ClangBuiltLinux/linux/issues/515):
we don't force the specified symbol to appear in .symtab This is a deliberate decision.

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D88945
This commit is contained in:
Fangrui Song 2020-10-07 08:45:24 -07:00
parent b57451b011
commit db1988f038
2 changed files with 12 additions and 1 deletions

View File

@ -1992,7 +1992,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Handle -u/--undefined before input files. If both a.a and b.so define foo,
// -u foo a.a b.so will fetch a.a.
for (StringRef name : config->undefined)
addUnusedUndefined(name);
addUnusedUndefined(name)->referenced = true;
// Add all files to the symbol table. This will add almost all
// symbols that we need to the symbol table. This process might

View File

@ -17,6 +17,17 @@
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
## -u specifies a STB_DEFAULT undefined symbol, so the definition from %t2.o is
## fetched.
# RUN: ld.lld -u foo %t1.o --start-lib %t2.o -o %t1
# RUN: llvm-readobj --syms %t1 | FileCheck %s --check-prefix=CHECK-U
# CHECK-U: Name: foo
# CHECK-U: Binding:
# CHECK-U-SAME: Global
# CHECK-U: Section:
# CHECK-U-SAME: .text
.weak foo
call foo@PLT