diff options
author | Fangrui Song <i@maskray.me> | 2024-05-31 22:35:31 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2024-05-31 22:35:31 -0700 |
commit | 0f3d646cefbe00b4a1037dc68e9d76e5470e805f (patch) | |
tree | 602b6cdaf8353b71ab75f589bbacb78b0b81ee2e /lld/ELF | |
parent | 59116e0941c7f406526fc37acf52845bd8380402 (diff) | |
download | llvm-0f3d646cefbe00b4a1037dc68e9d76e5470e805f.zip llvm-0f3d646cefbe00b4a1037dc68e9d76e5470e805f.tar.gz llvm-0f3d646cefbe00b4a1037dc68e9d76e5470e805f.tar.bz2 |
[ELF] Simplify findOrphanPos. NFC
Simplify the loop that considers sections of the same proximity. The two
involved conditions are due to:
* https://reviews.llvm.org/D111717 ("[ELF] Avoid adding an orphan section to a less suitable segment") and
* https://reviews.llvm.org/D112925 ("[ELF] Better resemble GNU ld when placing orphan sections into memory regions")
Diffstat (limited to 'lld/ELF')
-rw-r--r-- | lld/ELF/Writer.cpp | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 05f2e95..c90bbee 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -949,25 +949,22 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b, } if (!isa<OutputDesc>(*i)) return e; - auto foundSec = &cast<OutputDesc>(*i)->osec; - - // Consider all existing sections with the same proximity. - unsigned sortRank = sec->sortRank; - if (script->hasPhdrsCommands() || !script->memoryRegions.empty()) - // Prevent the orphan section to be placed before the found section. If - // custom program headers are defined, that helps to avoid adding it to a - // previous segment and changing flags of that segment, for example, making - // a read-only segment writable. If memory regions are defined, an orphan - // section should continue the same region as the found section to better - // resemble the behavior of GNU ld. - sortRank = std::max(sortRank, foundSec->sortRank); - for (; i != e; ++i) { - auto *curSecDesc = dyn_cast<OutputDesc>(*i); - if (!curSecDesc || !curSecDesc->osec.hasInputSections) - continue; - if (getRankProximity(sec, curSecDesc) != proximity || - sortRank < curSecDesc->osec.sortRank) - break; + + // If i's rank is larger, the orphan section can be placed before i. + // + // However, don't do this if custom program headers are defined. Otherwise, + // adding the orphan to a previous segment can change its flags, for example, + // making a read-only segment writable. If memory regions are defined, an + // orphan section should continue the same region as the found section to + // better resemble the behavior of GNU ld. + bool mustAfter = script->hasPhdrsCommands() || !script->memoryRegions.empty(); + if (cast<OutputDesc>(*i)->osec.sortRank <= sec->sortRank || mustAfter) { + while (++i != e) { + auto *cur = dyn_cast<OutputDesc>(*i); + if (cur && cur->osec.hasInputSections && + getRankProximity(sec, cur) != proximity) + break; + } } auto isOutputSecWithInputSections = [](SectionCommand *cmd) { |