Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -1511,10 +1511,26 @@ // 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); - for (OutputSection *Sec : OutputSections) - if (needsPtLoad(Sec) && isRelroSection(Sec)) - RelRo->add(Sec); + 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); Index: lld/trunk/test/ELF/relro-non-contiguous.s =================================================================== --- lld/trunk/test/ELF/relro-non-contiguous.s +++ lld/trunk/test/ELF/relro-non-contiguous.s @@ -0,0 +1,28 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o +// RUN: ld.lld -shared %t.o %t2.o -o %t.so + +// Place the .got.plt (non relro) immediately after .dynamic. This is the +// reverse order of the non-linker script case. The linker created .bss.rel.ro +// section will be placed after .got.plt causing the relro to be non-contiguous. +// RUN: echo "SECTIONS { \ +// RUN: .dynamic : { *(.dynamic) } \ +// RUN: .got.plt : { *(.got.plt) } \ +// RUN: } " > %t.script +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o + +// Expect error for non-contiguous relro +// RUN: not ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 | FileCheck %s +// No error when we do not request relro. +// RUN: ld.lld %t3.o %t.so -z norelro -o %t --script=%t.script +// REQUIRES: x86 + +// CHECK: error: section: .bss.rel.ro is not contiguous with other relro sections + .section .text, "ax", @progbits + .global _start + .global bar + .global foo +_start: + .quad bar + .quad foo +