forked from OSchip/llvm-project
[ELF] resolveUndefined: ignore undefined symbols in SharedFile for Undefined and SharedSymbol
If %t1.o has a weak reference on foo, and %t2.so has a non-weak reference on foo: `ld.lld %t1.o %t2.so -o %t` We incorrectly set the binding of the undefined foo to STB_GLOBAL. Fix this by ignoring undefined symbols in a SharedFile for Undefined and SharedSymbol. This fixes the binding of pthread_once when the program links against both librt.so and libpthread.so ``` a.o: STB_WEAK reference to pthread_once librt.so: STB_GLOBAL reference to pthread_once # should be ignored libstdc++.so: STB_WEAK reference to pthread_once # should be ignored libgcc_s.so.1: STB_WEAK reference to pthread_once # should be ignored ``` The STB_GLOBAL pthread_once issue (not fixed by D63974) can cause a link error when the result DSO is used to link another DSO with -z defs if -lpthread is not specified. (libstdc++.so.6 not having a dependency on libpthread.so is a really nasty hack...) We happened to create a weak undef before D63974 because libgcc_s.so.1 was linked the last and it changed the binding again to weak. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D64136 llvm-svn: 365129
This commit is contained in:
parent
555d743fcf
commit
f347541fbc
|
@ -410,18 +410,7 @@ void Symbol::resolveUndefined(const Undefined &Other) {
|
|||
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<SharedSymbol>(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 @@ void Symbol::resolveUndefined(const Undefined &Other) {
|
|||
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<SharedFile>(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<SharedSymbol>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue