mirror of
https://github.com/intel/llvm.git
synced 2026-02-07 16:11:27 +08:00
[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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user