Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -144,6 +144,7 @@ bool ZNodlopen; bool ZNow; bool ZOrigin; + bool ZReadOnlyDynamic; bool ZRelro; bool ZText; bool ExitEarly; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -687,6 +687,7 @@ Config->ZNodlopen = hasZOption(Args, "nodlopen"); Config->ZNow = hasZOption(Args, "now"); Config->ZOrigin = hasZOption(Args, "origin"); + Config->ZReadOnlyDynamic = hasZOption(Args, "rodynamic"); Config->ZRelro = !hasZOption(Args, "norelro"); Config->ZStackSize = getZOptionValue(Args, "stack-size", 0); Config->ZText = !hasZOption(Args, "notext"); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1008,7 +1008,8 @@ // .dynamic section is not writable on MIPS. // See "Special Section" in Chapter 4 in the following document: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - if (Config->EMachine == EM_MIPS) + // Users may want to make .dynamic read-only on other systems as well. + if (Config->EMachine == EM_MIPS || Config->ZReadOnlyDynamic) this->Flags = SHF_ALLOC; addEntries(); @@ -1053,7 +1054,8 @@ if (DtFlags1) add({DT_FLAGS_1, DtFlags1}); - if (!Config->Shared && !Config->Relocatable) + //DT_DEBUG will cause a segfault if .dynamic is read-only + if (!Config->Shared && !Config->Relocatable && !Config->ZReadOnlyDynamic) add({DT_DEBUG, (uint64_t)0}); } Index: test/ELF/rodynamic.s =================================================================== --- /dev/null +++ test/ELF/rodynamic.s @@ -0,0 +1,13 @@ +# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +# RUN: ld.lld -shared -z rodynamic %t.o -o %t.so +# RUN: llvm-readobj -sections %t.so | FileCheck %s + +.globl _start +_start: + +# CHECK: Section { +# CHECK: Name: .dynamic +# CHECK-NEXT: Type: SHT_DYNAMIC +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ]