@@ -111,11 +111,11 @@ template <class ELFT> class ICF {
111111 Relocs<RelTy> relsB);
112112
113113 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);
116116
117117 bool equalsConstant (InputSection *a, InputSection *b);
118- bool equalsVariable (const InputSection *a, const InputSection *b);
118+ bool equalsVariable (InputSection *a, InputSection *b);
119119
120120 size_t findBoundary (size_t begin, size_t end);
121121
@@ -315,7 +315,7 @@ bool ICF<ELFT>::constantEq(InputSection *secA, Relocs<RelTy> ra,
315315 if (isa<InputSection>(da->section )) {
316316 if (da->value + addA == db->value + addB) {
317317 // For non-trivial relocations, if we cannot merge symbols together,
318- // we must not merge them .
318+ // we must not merge sections either .
319319 if (!isTrivialRelocation (secA, sa, *rai) &&
320320 !canMergeSymbols (addA, addB))
321321 return false ;
@@ -392,8 +392,8 @@ getRelocTargetSyms(const InputSection *sec) {
392392// relocations point to the same section in terms of ICF.
393393template <class ELFT >
394394template <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) {
397397 assert (ra.size () == rb.size ());
398398
399399 auto rai = ra.begin (), rae = ra.end (), rbi = rb.begin ();
@@ -407,6 +407,15 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
407407 auto *da = cast<Defined>(&sa);
408408 auto *db = cast<Defined>(&sb);
409409
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+
410419 // We already dealt with absolute and non-InputSection symbols in
411420 // constantEq, and for InputSections we have already checked everything
412421 // except the equivalence class.
@@ -430,7 +439,7 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
430439
431440// Compare "moving" part of two InputSections, namely relocation targets.
432441template <class ELFT >
433- bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
442+ bool ICF<ELFT>::equalsVariable(InputSection *a, InputSection *b) {
434443 const RelsOrRelas<ELFT> ra = a->template relsOrRelas <ELFT>();
435444 const RelsOrRelas<ELFT> rb = b->template relsOrRelas <ELFT>();
436445 if (ra.areRelocsCrel () || rb.areRelocsCrel ())
@@ -610,9 +619,7 @@ template <class ELFT> void ICF<ELFT>::run() {
610619 assert (syms.size () == replacedSyms.size () &&
611620 " Should have same number of syms!" );
612621 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 ))
616623 continue ;
617624 symbolEquivalence.unionSets (syms[i].first , replacedSyms[i].first );
618625 }
0 commit comments