aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-05-31 22:35:31 -0700
committerFangrui Song <i@maskray.me>2024-05-31 22:35:31 -0700
commit0f3d646cefbe00b4a1037dc68e9d76e5470e805f (patch)
tree602b6cdaf8353b71ab75f589bbacb78b0b81ee2e /lld/ELF
parent59116e0941c7f406526fc37acf52845bd8380402 (diff)
downloadllvm-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.cpp35
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) {