Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1793,8 +1793,6 @@ return PF_R | PF_W | PF_X; if (Config->ExecuteOnly && (Flags & PF_X)) return Flags & ~PF_R; - if (Config->SingleRoRx && !(Flags & PF_W)) - return Flags | PF_X; return Flags; } @@ -1822,6 +1820,10 @@ Load->add(Out::ElfHeader); Load->add(Out::ProgramHeaders); + auto isRO = [](uint64_t Flags) { + return ((Flags & PF_X) || (Flags & PF_W)) ? false : true; + }; + for (OutputSection *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -1839,12 +1841,14 @@ 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) { Load = AddHdr(PT_LOAD, NewFlags); - Flags = NewFlags; + } else if ((Load->p_flags != NewFlags)) { + if (Config->SingleRoRx && isRO(Load->p_flags)) + Load->p_flags = NewFlags; + else + Load = AddHdr(PT_LOAD, NewFlags); } - Load->add(Sec); } Index: test/ELF/linkerscript/at-self-reference.s =================================================================== --- test/ELF/linkerscript/at-self-reference.s +++ test/ELF/linkerscript/at-self-reference.s @@ -16,9 +16,8 @@ # CHECK-NEXT: PhysicalAddress: 0x1000 # CHECK-NEXT: FileSize: 3 # CHECK-NEXT: MemSize: 3 -# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) -# CHECK-NEXT: PF_X (0x1) # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 4096 # CHECK-NEXT: } Index: test/ELF/linkerscript/at.s =================================================================== --- test/ELF/linkerscript/at.s +++ test/ELF/linkerscript/at.s @@ -21,7 +21,6 @@ # CHECK-NEXT: MemSize: 16 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R -# CHECK-NEXT: PF_X # CHECK-NEXT: ] # CHECK-NEXT: Alignment: # CHECK-NEXT: } @@ -34,7 +33,6 @@ # CHECK-NEXT: MemSize: 8 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R -# CHECK-NEXT: PF_X # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 4096 # CHECK-NEXT: } @@ -47,7 +45,6 @@ # CHECK-NEXT: MemSize: 8 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R -# CHECK-NEXT: PF_X # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 4096 # CHECK-NEXT: } Index: test/ELF/linkerscript/overlay.test =================================================================== --- test/ELF/linkerscript/overlay.test +++ test/ELF/linkerscript/overlay.test @@ -26,5 +26,5 @@ # CHECK: Program Headers: # CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align -# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000004000 0x000008 0x000008 R E 0x1000 +# CHECK-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000004000 0x000008 0x000008 R 0x1000 # CHECK-NEXT: LOAD 0x002000 0x0000000000001000 0x0000000000004008 0x000009 0x000009 R E 0x1000 Index: test/ELF/no-rosegment.s =================================================================== --- /dev/null +++ test/ELF/no-rosegment.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: . = 0x200000; \ +# RUN: .rodata : { *(.rodata) } \ +# RUN: }" > %t.script +# RUN: ld.lld --no-rosegment -o %t -T %t.script %t.o +# RUN: llvm-readelf -l %t | FileCheck %s + +.text +nop +.rodata + .word 0x41 + .word 0x42 + .word 0x43 + .word 0x44 +#CHECK: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000001 0x000001 R E 0x1000 +#CHECK-NEXT: LOAD 0x002000 0x0000000000200000 0x0000000000200000 0x000008 0x000008 R 0x1000 Index: test/ELF/phdr-align.s =================================================================== --- test/ELF/phdr-align.s +++ test/ELF/phdr-align.s @@ -32,8 +32,8 @@ # CHECK-NEXT: SHF_ALLOC # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x158 -# CHECK-NEXT: Offset: 0x158 +# CHECK-NEXT: Address: 0x120 +# CHECK-NEXT: Offset: 0x120 # CHECK-NEXT: Size: 6 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -48,8 +48,8 @@ # CHECK-NEXT: SHF_ALLOC # CHECK-NEXT: SHF_WRITE # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x15E -# CHECK-NEXT: Offset: 0x15E +# CHECK-NEXT: Address: 0x126 +# CHECK-NEXT: Offset: 0x126 # CHECK-NEXT: Size: 2 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -64,8 +64,8 @@ # CHECK-NEXT: SHF_ALLOC # CHECK-NEXT: SHF_EXECINSTR # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x160 -# CHECK-NEXT: Offset: 0x160 +# CHECK-NEXT: Address: 0x128 +# CHECK-NEXT: Offset: 0x128 # CHECK-NEXT: Size: 1 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0