[lld][ELF] remove empty SyntheticSections from inputSections

Change removeUnusedSyntheticSections() to actually remove empty
SyntheticSections in inputSections.

In addition to doing what removeUnusedSyntheticSections() was meant
to do, this will also make the shuffle-sections tests, which shuffles
inputSections, less sensitive to empty Synthetic Sections that
will not appear in the final image.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D106427

Change-Id: I589eaf596472161a4395fb658aea0fad73318088
This commit is contained in:
Amilendra Kodithuwakku
2021-07-27 22:29:25 +01:00
parent 3888039403
commit b9cf1769de
3 changed files with 42 additions and 24 deletions

View File

@@ -1889,26 +1889,44 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
// out to be empty.
static void removeUnusedSyntheticSections() {
// All input synthetic sections that can be empty are placed after
// all regular ones. We iterate over them all and exit at first
// non-synthetic.
for (InputSectionBase *s : llvm::reverse(inputSections)) {
SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
if (!ss)
return;
OutputSection *os = ss->getParent();
if (!os || ss->isNeeded())
continue;
// all regular ones. Reverse iterate to find the first synthetic section
// after a non-synthetic one which will be our starting point.
auto start = std::find_if(inputSections.rbegin(), inputSections.rend(),
[](InputSectionBase *s) {
return !isa<SyntheticSection>(s);
})
.base();
// If we reach here, then ss is an unused synthetic section and we want to
// remove it from the corresponding input section description, and
// orphanSections.
for (BaseCommand *b : os->sectionCommands)
if (auto *isd = dyn_cast<InputSectionDescription>(b))
llvm::erase_if(isd->sections,
[=](InputSection *isec) { return isec == ss; });
llvm::erase_if(script->orphanSections,
[=](const InputSectionBase *isec) { return isec == ss; });
}
DenseSet<InputSectionDescription *> isdSet;
// Mark unused synthetic sections for deletion
auto end = std::stable_partition(
start, inputSections.end(), [&](InputSectionBase *s) {
SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
OutputSection *os = ss->getParent();
if (!os || ss->isNeeded())
return true;
// If we reach here, then ss is an unused synthetic section and we want
// to remove it from the corresponding input section description, and
// orphanSections.
for (BaseCommand *b : os->sectionCommands)
if (auto *isd = dyn_cast<InputSectionDescription>(b))
isdSet.insert(isd);
llvm::erase_if(
script->orphanSections,
[=](const InputSectionBase *isec) { return isec == ss; });
return false;
});
DenseSet<InputSectionBase *> unused(end, inputSections.end());
for (auto *isd : isdSet)
llvm::erase_if(isd->sections,
[=](InputSection *isec) { return unused.count(isec); });
// Erase unused synthetic sections.
inputSections.erase(end, inputSections.end());
}
// Create output section objects and add them to OutputSections.

View File

@@ -21,12 +21,12 @@
# CHECK: Hex dump of section '.init_array'
# CHECK-NEXT: 0x{{[0-9a-f]+}} ff
# ORDERED-SAME: 000102 03040506 0708090a 0b
# SHUFFLED-SAME: 080301 04050907 0b020a06 00
# SHUFFLED-SAME: 070201 0006090a 040b0503 08
# CHECK: Hex dump of section '.fini_array'
# CHECK-NEXT: 0x{{[0-9a-f]+}} ff
# ORDERED-SAME: 000102 03040506 0708090a 0b
# SHUFFLED-SAME: 0a0405 08070b02 03090006 01
# SHUFFLED-SAME: 070008 0a040209 03010b06 05
## With a SECTIONS command, SHT_INIT_ARRAY prirotities are ignored.
## All .init_array* are shuffled together.
@@ -42,7 +42,7 @@
# CHECK2: Hex dump of section '.init_array'
# ORDERED2-NEXT: 0x{{[0-9a-f]+}} 00010203 04050607 08090a0b ff
# SHUFFLED2-NEXT: 0x{{[0-9a-f]+}} 08030104 0509070b 02ff0a06 00
# SHUFFLED2-NEXT: 0x{{[0-9a-f]+}} 07020100 06090a04 0b050308 ff
.irp i,0,1,2,3,4,5,6,7,8,9,10,11
.section .init,"ax",@progbits,unique,\i

View File

@@ -10,7 +10,7 @@
# RUN: ld.lld --shuffle-sections='*=1' %t.o -o %t1.out
# RUN: llvm-readelf -x .text %t1.out | FileCheck %s --check-prefix=SHUFFLE1
# SHUFFLE1: Hex dump of section '.text':
# SHUFFLE1-NEXT: 0203cccc 0104
# SHUFFLE1-NEXT: 01020403
## Test that --shuffle-sections= can be used with --symbol-ordering-file
# RUN: echo "foo" > %t_order.txt
@@ -19,7 +19,7 @@
# RUN: ld.lld --symbol-ordering-file %t_order.txt --shuffle-sections='*=2' %t.o -o %t2.out
# RUN: llvm-readelf -x .text %t2.out | FileCheck %s --check-prefix=SHUFFLE2
# SHUFFLE2: Hex dump of section '.text':
# SHUFFLE2-NEXT: 02cccccc 010403
# SHUFFLE2-NEXT: 02cccccc 010304
# RUN: ld.lld --symbol-ordering-file %t_order.txt --shuffle-sections='*=3' %t.o -o %t3.out
# RUN: llvm-readelf -x .text %t3.out | FileCheck %s --check-prefix=SHUFFLE3