[PATCH] D66719: [ELF] Do not ICF two sections with different output sections when there is a linker script
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 25 09:54:31 PDT 2019
MaskRay created this revision.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
MaskRay abandoned this revision.
MaskRay added a comment.
D66717 <https://reviews.llvm.org/D66717> should be better
This complements D47241 <https://reviews.llvm.org/D47241> for the non-linker-script (getOutputSectionName) case.
This implements the unfold approach as briefed at https://reviews.llvm.org/D54422#1302994
// Do not ICF fold input sections between output sections. If the output
// sections of sec and the InputSection it gets folded into are different,
// unfold it. sec->repl may have increased alignment or be have moved to the
// main partition, but that does not matter.
--print-icf-sections is not handled.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D66719
Files:
ELF/ICF.cpp
ELF/LinkerScript.cpp
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -378,7 +378,7 @@
size_t sizeBefore = ret.size();
for (InputSectionBase *sec : inputSections) {
- if (!sec->isLive() || sec->assigned)
+ if (sec->assigned || (!sec->isLive() && sec->repl == sec))
continue;
// For -emit-relocs we have to ignore entries like
@@ -421,8 +421,11 @@
if (s == mainPart->hashTab)
mainPart->hashTab = nullptr;
- s->assigned = false;
+ // Entirely discarded. s->repl != s indicates a section that can be unfolded
+ // later.
s->markDead();
+ s->repl = s;
+
discard(s->dependentSections);
}
}
@@ -461,6 +464,7 @@
ctx = deleter.get();
ctx->outSec = aether;
+ DenseMap<OutputSection *, std::vector<InputSection *>> inputs;
size_t i = 0;
// Add input sections to output sections.
for (BaseCommand *base : sectionCommands) {
@@ -510,9 +514,9 @@
s->alignment = subalign;
}
- // Add input sections to an output section.
- for (InputSection *s : v)
- sec->addSection(s);
+ for (InputSection *&s : v)
+ s->parent = sec;
+ inputs[sec] = std::move(v);
sec->sectionIndex = i++;
if (sec->noload)
@@ -521,6 +525,28 @@
sec->flags &= ~(uint64_t)SHF_ALLOC;
}
}
+
+ // Do not ICF fold input sections between output sections. If the output
+ // sections of sec and the InputSection it gets folded into are different,
+ // unfold it. sec->repl may have increased alignment or be have moved to the
+ // main partition, but that does not matter.
+ for (auto &it : inputs)
+ for (InputSection *s : it.second)
+ if (s->repl != s && cast<InputSection>(s->repl)->getParent() != s->getParent()) {
+ s->repl = s;
+ s->markLive();
+ for (InputSection *dependent : s->dependentSections)
+ dependent->markLive();
+ }
+
+ // Delete garbage-collected or folded input sections.
+ for (auto &it : inputs) {
+ OutputSection *sec = it.first;
+ for (InputSection *&s : it.second)
+ if (s->isLive())
+ sec->addSection(s);
+ }
+
ctx = nullptr;
}
Index: ELF/ICF.cpp
===================================================================
--- ELF/ICF.cpp
+++ ELF/ICF.cpp
@@ -303,10 +303,10 @@
a->getSize() != b->getSize() || a->data() != b->data())
return false;
- // If two sections have different output sections, we cannot merge them.
- // FIXME: This doesn't do the right thing in the case where there is a linker
- // script. We probably need to move output section assignment before ICF to
- // get the correct behaviour here.
+ // If two sections have different output sections, we cannot merge them. When
+ // there is a linker script, getOutputSectionName may be inaccurate, sections
+ // going into different output sections may get folded but they will be
+ // unfolded in LinkerScript::processSectionCommands.
if (getOutputSectionName(a) != getOutputSectionName(b))
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66719.217051.patch
Type: text/x-patch
Size: 3110 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190825/8f327eb0/attachment-0001.bin>
More information about the llvm-commits
mailing list