@@ -111,11 +111,11 @@ template <class ELFT> class ICF {
111
111
Relocs<RelTy> relsB);
112
112
113
113
template <class RelTy >
114
- bool variableEq (const InputSection *a, Relocs<RelTy> relsA,
115
- const InputSection *b, Relocs<RelTy> relsB);
114
+ bool variableEq (InputSection *a, Relocs<RelTy> relsA, InputSection *b ,
115
+ Relocs<RelTy> relsB);
116
116
117
117
bool equalsConstant (InputSection *a, InputSection *b);
118
- bool equalsVariable (const InputSection *a, const InputSection *b);
118
+ bool equalsVariable (InputSection *a, InputSection *b);
119
119
120
120
size_t findBoundary (size_t begin, size_t end);
121
121
@@ -315,7 +315,7 @@ bool ICF<ELFT>::constantEq(InputSection *secA, Relocs<RelTy> ra,
315
315
if (isa<InputSection>(da->section )) {
316
316
if (da->value + addA == db->value + addB) {
317
317
// For non-trivial relocations, if we cannot merge symbols together,
318
- // we must not merge them .
318
+ // we must not merge sections either .
319
319
if (!isTrivialRelocation (secA, sa, *rai) &&
320
320
!canMergeSymbols (addA, addB))
321
321
return false ;
@@ -392,8 +392,8 @@ getRelocTargetSyms(const InputSection *sec) {
392
392
// relocations point to the same section in terms of ICF.
393
393
template <class ELFT >
394
394
template <class RelTy >
395
- bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
396
- const InputSection *secB, Relocs<RelTy> rb) {
395
+ bool ICF<ELFT>::variableEq(InputSection *secA, Relocs<RelTy> ra,
396
+ InputSection *secB, Relocs<RelTy> rb) {
397
397
assert (ra.size () == rb.size ());
398
398
399
399
auto rai = ra.begin (), rae = ra.end (), rbi = rb.begin ();
@@ -407,6 +407,15 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
407
407
auto *da = cast<Defined>(&sa);
408
408
auto *db = cast<Defined>(&sb);
409
409
410
+ // Prevent sections containing local symbols from merging into sections with
411
+ // global symbols, or vice-versa. This is to prevent local-global symbols
412
+ // getting merged into each other (done later in ICF). We do this as
413
+ // post-ICF passes cannot handle duplicates when iterating over local
414
+ // symbols. There are also assertions that prevent this.
415
+ if ((!da->isGlobal () || !db->isGlobal ()) &&
416
+ !isTrivialRelocation (secA, sa, *rai))
417
+ return false ;
418
+
410
419
// We already dealt with absolute and non-InputSection symbols in
411
420
// constantEq, and for InputSections we have already checked everything
412
421
// except the equivalence class.
@@ -430,7 +439,7 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
430
439
431
440
// Compare "moving" part of two InputSections, namely relocation targets.
432
441
template <class ELFT >
433
- bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
442
+ bool ICF<ELFT>::equalsVariable(InputSection *a, InputSection *b) {
434
443
const RelsOrRelas<ELFT> ra = a->template relsOrRelas <ELFT>();
435
444
const RelsOrRelas<ELFT> rb = b->template relsOrRelas <ELFT>();
436
445
if (ra.areRelocsCrel () || rb.areRelocsCrel ())
@@ -610,9 +619,7 @@ template <class ELFT> void ICF<ELFT>::run() {
610
619
assert (syms.size () == replacedSyms.size () &&
611
620
" Should have same number of syms!" );
612
621
for (size_t i = 0 ; i < syms.size (); i++) {
613
- if (syms[i].first == replacedSyms[i].first ||
614
- !syms[i].first ->isGlobal () || !replacedSyms[i].first ->isGlobal () ||
615
- !canMergeSymbols (syms[i].second , replacedSyms[i].second ))
622
+ if (!canMergeSymbols (syms[i].second , replacedSyms[i].second ))
616
623
continue ;
617
624
symbolEquivalence.unionSets (syms[i].first , replacedSyms[i].first );
618
625
}
0 commit comments