Skip to content

Commit 6c41c38

Browse files
committed
Add tests for to prevent local-global merging
1 parent 6b435f9 commit 6c41c38

File tree

2 files changed

+62
-24
lines changed

2 files changed

+62
-24
lines changed

lld/ELF/ICF.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,11 @@ template <class ELFT> void ICF<ELFT>::run() {
618618
getRelocTargetSyms<ELFT>(sections[i]);
619619
assert(syms.size() == replacedSyms.size() &&
620620
"Should have same number of syms!");
621-
for (size_t i = 0; i < syms.size(); i++) {
622-
if (!canMergeSymbols(syms[i].second, replacedSyms[i].second))
621+
for (size_t j = 0; j < syms.size(); j++) {
622+
if (!syms[j].first->isGlobal() || !replacedSyms[j].first->isGlobal() ||
623+
!canMergeSymbols(syms[j].second, replacedSyms[j].second))
623624
continue;
624-
symbolEquivalence.unionSets(syms[i].first, replacedSyms[i].first);
625+
symbolEquivalence.unionSets(syms[j].first, replacedSyms[j].first);
625626
}
626627

627628
// At this point we know sections merged are fully identical and hence

lld/test/ELF/icf-addend.s

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,50 @@
22
# RUN: rm -rf %t && split-file %s %t && cd %t
33

44
#--- trivial-relocation.s
5-
# For trivial relocations, merging two equivalent sections is allowed but we must not
6-
# merge their symbols if addends are different.
5+
# Tests following for trivial relocations:
6+
# 1. Merging two equivalent sections is allowed but we must not merge their symbols if addends are different.
7+
# 2. Local symbols should not be merged together even though their sections can be merged together.
78

89
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux trivial-relocation.s -o trivial.o
9-
# RUN: ld.lld trivial.o -o /dev/null --icf=all --print-icf-sections | FileCheck %s
10+
# RUN: ld.lld trivial.o -o /dev/null --icf=all --print-icf-sections | FileCheck %s --check-prefix=TRIVIAL
1011

11-
# CHECK: selected section {{.*}}:(.text.f1)
12-
# CHECK: removing identical section {{.*}}:(.text.f2)
13-
# CHECK-NOT: redirecting 'y' in symtab to x
14-
# CHECK-NOT: redirecting 'y' to 'x'
12+
# TRIVIAL: selected section {{.*}}:(.rodata.sec1)
13+
# TRIVIAL-NEXT: removing identical section {{.*}}:(.rodata.sec2)
14+
# TRIVIAL-NEXT: selected section {{.*}}:(.text.f1)
15+
# TRIVIAL-NEXT: removing identical section {{.*}}:(.text.f2)
16+
# TRIVIAL-NEXT: removing identical section {{.*}}:(.text.f1_local)
17+
# TRIVIAL-NEXT: removing identical section {{.*}}:(.text.f2_local)
1518

16-
.globl x, y
19+
.addrsig
1720

18-
.section .rodata,"a",@progbits
21+
.globl x_glob, y_glob
22+
23+
.section .rodata.sec1,"a",@progbits
24+
x_glob:
25+
.long 11
26+
y_glob:
27+
.long 12
28+
29+
.section .rodata.sec2,"a",@progbits
1930
x:
2031
.long 11
2132
y:
2233
.long 12
2334

2435
.section .text.f1,"ax",@progbits
2536
f1:
26-
movq x+4(%rip), %rax
37+
movq x_glob+4(%rip), %rax
2738

2839
.section .text.f2,"ax",@progbits
2940
f2:
41+
movq y_glob(%rip), %rax
42+
43+
.section .text.f1_local,"ax",@progbits
44+
f1_local:
45+
movq x+4(%rip), %rax
46+
47+
.section .text.f2_local,"ax",@progbits
48+
f2_local:
3049
movq y(%rip), %rax
3150

3251
.section .text._start,"ax",@progbits
@@ -36,34 +55,52 @@ call f1
3655
call f2
3756

3857
#--- non-trivial-relocation.s
39-
# For non-trivial relocations, we must not merge sections if addends are different.
40-
# Not merging sections would automatically disable symbol merging.
58+
# Tests following for non-trivial relocations:
59+
# 1. We must not merge sections if addends are different.
60+
# 2. We must not merge sections pointing to local and global symbols.
4161

42-
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux trivial-relocation.s -o trivial.o
43-
# RUN: ld.lld trivial.o -o /dev/null --icf=all --print-icf-sections | FileCheck %s
62+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux non-trivial-relocation.s -o non-trivial.o
63+
# RUN: ld.lld non-trivial.o -o /dev/null --icf=all --print-icf-sections | FileCheck %s --check-prefix=NONTRIVIAL
64+
65+
# NONTRIVIAL: selected section {{.*}}:(.rodata.sec1)
66+
# NONTRIVIAL-NEXT: removing identical section {{.*}}:(.rodata.sec2)
67+
# NONTRIVIAL-NEXT: selected section {{.*}}:(.text.f1_local)
68+
# NONTRIVIAL-NEXT: removing identical section {{.*}}:(.text.f2_local)
4469

45-
# CHECK-NOT: selected section {{.*}}:(.text.f1)
46-
# CHECK-NOT: removing identical section {{.*}}:(.text.f2)
70+
.addrsig
4771

48-
.globl x, y
72+
.globl x_glob, y_glob
4973

50-
.section .rodata,"a",@progbits
74+
.section .rodata.sec1,"a",@progbits
75+
x_glob:
76+
.long 11
77+
y_glob:
78+
.long 12
79+
80+
.section .rodata.sec2,"a",@progbits
5181
x:
5282
.long 11
5383
y:
5484
.long 12
5585

5686
.section .text.f1,"ax",@progbits
5787
f1:
58-
movq x+4@GOTPCREL(%rip), %rax
88+
movq x_glob+4@GOTPCREL(%rip), %rax
5989

6090
.section .text.f2,"ax",@progbits
6191
f2:
62-
movq y@GOTPCREL(%rip), %rax
92+
movq y_glob@GOTPCREL(%rip), %rax
93+
94+
.section .text.f1_local,"ax",@progbits
95+
f1_local:
96+
movq x+4(%rip), %rax
97+
98+
.section .text.f2_local,"ax",@progbits
99+
f2_local:
100+
movq y(%rip), %rax
63101

64102
.section .text._start,"ax",@progbits
65103
.globl _start
66104
_start:
67105
call f1
68106
call f2
69-

0 commit comments

Comments
 (0)