diff options
Diffstat (limited to 'lld/ELF')
-rw-r--r-- | lld/ELF/Writer.cpp | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c90bbee..58ae207 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -950,6 +950,11 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b, if (!isa<OutputDesc>(*i)) return e; + auto isOutputSecWithInputSections = [](SectionCommand *cmd) { + auto *osd = dyn_cast<OutputDesc>(cmd); + return osd && osd->osec.hasInputSections; + }; + // 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, @@ -959,30 +964,25 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b, // 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) + for (auto j = ++i; j != e; ++j) { + if (!isOutputSecWithInputSections(*j)) + continue; + if (getRankProximity(sec, *j) != proximity) break; + i = j + 1; } + } else { + for (; i != b; --i) + if (isOutputSecWithInputSections(i[-1])) + break; } - auto isOutputSecWithInputSections = [](SectionCommand *cmd) { - auto *osd = dyn_cast<OutputDesc>(cmd); - return osd && osd->osec.hasInputSections; - }; - auto j = - std::find_if(std::make_reverse_iterator(i), std::make_reverse_iterator(b), - isOutputSecWithInputSections); - i = j.base(); - // As a special case, if the orphan section is the last section, put // it at the very end, past any other commands. // This matches bfd's behavior and is convenient when the linker script fully // specifies the start of the file, but doesn't care about the end (the non // alloc sections for example). - auto nextSec = std::find_if(i, e, isOutputSecWithInputSections); - if (nextSec == e) + if (std::find_if(i, e, isOutputSecWithInputSections) == e) return e; while (i != e && shouldSkip(*i)) |