diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -1575,6 +1575,7 @@ .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) .Case("PT_GNU_STACK", PT_GNU_STACK) .Case("PT_GNU_RELRO", PT_GNU_RELRO) + .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE) .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2369,6 +2369,12 @@ addHdr(PT_GNU_EH_FRAME, part.ehFrameHdr->getParent()->getPhdrFlags()) ->add(part.ehFrameHdr->getParent()); + // PT_OPENBSD_MUTABLE is an OpenBSD-specific feature. That makes + // the dynamic linker fill the segment with zero data, like bss, but + // it can be treated differently. + if (OutputSection *cmd = findSection(".openbsd.mutable", partNo)) + addHdr(PT_OPENBSD_MUTABLE, cmd->getPhdrFlags())->add(cmd); + // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes // the dynamic linker fill the segment with random data. if (OutputSection *cmd = findSection(".openbsd.randomdata", partNo)) diff --git a/lld/test/ELF/linkerscript/openbsd-mutable.s b/lld/test/ELF/linkerscript/openbsd-mutable.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/linkerscript/openbsd-mutable.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o +# RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_MUTABLE; } \ +# RUN: SECTIONS { . = SIZEOF_HEADERS; \ +# RUN: .text : { *(.text) } \ +# RUN: .openbsd.mutable : { *(.openbsd.mutable) } : rand }" > %t.script +# RUN: ld.lld --script %t.script %t.o -o %t +# RUN: llvm-readobj --program-headers -S %t | FileCheck %s + +# CHECK: ProgramHeader { +# CHECK: Type: PT_OPENBSD_MUTABLE (0x65A3DBE5) +# CHECK-NEXT: Offset: 0x74 +# CHECK-NEXT: VirtualAddress: 0x74 +# CHECK-NEXT: PhysicalAddress: 0x74 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } + +.section .openbsd.mutable, "a" +.quad 0 diff --git a/lld/test/ELF/openbsd-mutable.s b/lld/test/ELF/openbsd-mutable.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/openbsd-mutable.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: ld.lld %t -o %t.out +# RUN: llvm-readobj --program-headers %t.out | FileCheck %s + +# CHECK: ProgramHeader { +# CHECK: Type: PT_OPENBSD_MUTABLE (0x65A3DBE5) +# CHECK-NEXT: Offset: +# CHECK-NEXT: VirtualAddress: +# CHECK-NEXT: PhysicalAddress: +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } + +.section .openbsd.mutable, "a" +.quad 0