Skip to content

Commit dccd061

Browse files
MaskRaytru
authored andcommitted
[ELF] Suppress "duplicate symbol" when resolving STB_WEAK and STB_GNU_UNIQUE in different COMDATs
``` template <typename T> struct A { A() {} int value = 0; }; template <typename Value> struct B { static A<int> a; }; template <typename Value> A<int> B<Value>::a; inline int foo() { return B<int>::a.value; } ``` ``` clang++ -c -fno-pic a.cc -o weak.o g++ -c -fno-pic a.cc -o unique.o # --enable-gnu-unique-object # Duplicate symbol error. In postParse, we do not check `sym.binding` ld.lld -e 0 weak.o unique.o ``` Mixing GCC and Clang object files in this case is not ideal. .bss._ZGVN1BIiE1aE has different COMDAT groups. It appears to work in practice because the guard variable prevents harm due to double initialization. For the linker, we just stick with the rule that a weak binding does not cause "duplicate symbol" errors. Close llvm#58232 Differential Revision: https://reviews.llvm.org/D136381 (cherry picked from commit 0051b6b)
1 parent 5834fe6 commit dccd061

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,7 @@ template <class ELFT> void ObjFile<ELFT>::postParse() {
11571157
continue;
11581158
}
11591159

1160-
if (binding == STB_WEAK)
1160+
if (sym.binding == STB_WEAK || binding == STB_WEAK)
11611161
continue;
11621162
std::lock_guard<std::mutex> lock(mu);
11631163
ctx->duplicates.push_back({&sym, this, sec, eSym.st_value});

lld/test/ELF/comdat-binding2.s

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# REQUIRES: x86
2+
## Test we don't report duplicate definition errors when mixing Clang STB_WEAK
3+
## and GCC STB_GNU_UNIQUE symbols.
4+
5+
# RUN: rm -rf %t && split-file %s %t && cd %t
6+
# RUN: llvm-mc -filetype=obj -triple=x86_64 weak.s -o weak.o
7+
# RUN: llvm-mc -filetype=obj -triple=x86_64 unique.s -o unique.o
8+
# RUN: ld.lld weak.o unique.o -o weak
9+
# RUN: llvm-readelf -s weak | FileCheck %s --check-prefix=WEAK
10+
# RUN: ld.lld unique.o weak.o -o unique
11+
# RUN: llvm-readelf -s unique | FileCheck %s --check-prefix=UNIQUE
12+
13+
# WEAK: OBJECT WEAK DEFAULT [[#]] _ZN1BIiE1aE
14+
# UNIQUE: OBJECT UNIQUE DEFAULT [[#]] _ZN1BIiE1aE
15+
16+
#--- weak.s
17+
## Clang
18+
.type _ZN1BIiE1aE,@object
19+
.section .bss._ZN1BIiE1aE,"aGwR",@nobits,_ZN1BIiE1aE,comdat
20+
.weak _ZN1BIiE1aE
21+
_ZN1BIiE1aE:
22+
.zero 4
23+
24+
.type _ZGVN1BIiE1aE,@object
25+
.section .bss._ZGVN1BIiE1aE,"aGw",@nobits,_ZN1BIiE1aE,comdat
26+
.weak _ZGVN1BIiE1aE
27+
_ZGVN1BIiE1aE:
28+
.quad 0
29+
30+
#--- unique.s
31+
## GCC -fgnu-unique. Note the different group signature for the second group.
32+
.weak _ZN1BIiE1aE
33+
.section .bss._ZN1BIiE1aE,"awG",@nobits,_ZN1BIiE1aE,comdat
34+
.type _ZN1BIiE1aE, @gnu_unique_object
35+
_ZN1BIiE1aE:
36+
.zero 4
37+
38+
.weak _ZGVN1BIiE1aE
39+
.section .bss._ZGVN1BIiE1aE,"awG",@nobits,_ZGVN1BIiE1aE,comdat
40+
.type _ZGVN1BIiE1aE, @gnu_unique_object
41+
_ZGVN1BIiE1aE:
42+
.zero 8

0 commit comments

Comments
 (0)