diff options
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r-- | lld/ELF/Writer.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index ac332de2a057..713c54dee509 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1523,17 +1523,30 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() { // but sort must consider them all at once. std::vector<InputSection **> scriptSections; std::vector<InputSection *> sections; + bool started = false, stopped = false; for (BaseCommand *base : sec->sectionCommands) { if (auto *isd = dyn_cast<InputSectionDescription>(base)) { for (InputSection *&isec : isd->sections) { - scriptSections.push_back(&isec); - sections.push_back(isec); - - InputSection *link = isec->getLinkOrderDep(); - if (!link->getParent()) - error(toString(isec) + ": sh_link points to discarded section " + - toString(link)); + if (!(isec->flags & SHF_LINK_ORDER)) { + if (started) + stopped = true; + } else if (stopped) { + error(toString(isec) + ": SHF_LINK_ORDER sections in " + sec->name + + " are not contiguous"); + } else { + started = true; + + scriptSections.push_back(&isec); + sections.push_back(isec); + + InputSection *link = isec->getLinkOrderDep(); + if (!link->getParent()) + error(toString(isec) + ": sh_link points to discarded section " + + toString(link)); + } } + } else if (started) { + stopped = true; } } |