Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1946,6 +1946,29 @@ Load->add(Out::ElfHeader); Load->add(Out::ProgramHeaders); + // PT_GNU_RELRO includes all sections that should be marked as + // read-only by dynamic linker after proccessing relocations. + // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give + // an error message if more than one PT_GNU_RELRO PHDR is required. + PhdrEntry *RelRo = make(PT_GNU_RELRO, PF_R); + bool InRelroPhdr = false; + OutputSection *RelroEnd = nullptr; + for (OutputSection *Sec : OutputSections) { + if (!needsPtLoad(Sec)) + continue; + if (isRelroSection(Sec)) { + InRelroPhdr = true; + if (!RelroEnd) + RelRo->add(Sec); + else + error("section: " + Sec->Name + " is not contiguous with other relro" + + " sections"); + } else if (InRelroPhdr) { + InRelroPhdr = false; + RelroEnd = Sec; + } + } + for (OutputSection *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -1963,7 +1986,8 @@ if (((Sec->LMAExpr || (Sec->LMARegion && (Sec->LMARegion != Load->FirstSec->LMARegion))) && Load->LastSec != Out::ProgramHeaders) || - Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { + Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags || + Sec == RelroEnd) { Load = AddHdr(PT_LOAD, NewFlags); Flags = NewFlags; @@ -1984,28 +2008,6 @@ if (OutputSection *Sec = In.Dynamic->getParent()) AddHdr(PT_DYNAMIC, Sec->getPhdrFlags())->add(Sec); - // PT_GNU_RELRO includes all sections that should be marked as - // read-only by dynamic linker after proccessing relocations. - // Current dynamic loaders only support one PT_GNU_RELRO PHDR, give - // an error message if more than one PT_GNU_RELRO PHDR is required. - PhdrEntry *RelRo = make(PT_GNU_RELRO, PF_R); - bool InRelroPhdr = false; - bool IsRelroFinished = false; - for (OutputSection *Sec : OutputSections) { - if (!needsPtLoad(Sec)) - continue; - if (isRelroSection(Sec)) { - InRelroPhdr = true; - if (!IsRelroFinished) - RelRo->add(Sec); - else - error("section: " + Sec->Name + " is not contiguous with other relro" + - " sections"); - } else if (InRelroPhdr) { - InRelroPhdr = false; - IsRelroFinished = true; - } - } if (RelRo->FirstSec) Ret.push_back(RelRo);