Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -58,6 +58,7 @@ unsigned Type; bool HasFilehdr; bool HasPhdrs; + unsigned Flags; }; // ScriptConfiguration holds linker script parse results. Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -326,7 +326,7 @@ std::vector Phdrs; for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { - Phdrs.emplace_back(Cmd.Type, PF_R); + Phdrs.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); Phdr &Added = Phdrs.back(); if (Cmd.HasFilehdr) @@ -379,6 +379,8 @@ // Assign headers specified by linker script for (size_t Id : PhdrIds) { Phdrs[Id].add(Sec); + if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) + Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); Phdrs[Id].H.p_flags |= toPhdrFlags(Sec->getFlags()); } } else { @@ -657,7 +659,7 @@ expect("{"); while (!Error && !skip("}")) { StringRef Tok = next(); - Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false}); + Opt.PhdrsCommands.push_back({Tok, PT_NULL, false, false, UINT_MAX}); PhdrsCommand &PhdrCmd = Opt.PhdrsCommands.back(); PhdrCmd.Type = readPhdrType(); @@ -669,7 +671,11 @@ PhdrCmd.HasFilehdr = true; else if (Tok == "PHDRS") PhdrCmd.HasPhdrs = true; - else + else if (Tok == "FLAGS") { + expect("("); + next().getAsInteger(0, PhdrCmd.Flags); + expect(")"); + } else setError("unexpected header attribute: " + Tok); } while (!Error); } Index: test/ELF/linkerscript-phdrs-flags.s =================================================================== --- test/ELF/linkerscript-phdrs-flags.s +++ test/ELF/linkerscript-phdrs-flags.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (7);} \ +# RUN: SECTIONS { \ +# RUN: . = 0x10000200; \ +# RUN: .text : {*(.text.*)} :all \ +# RUN: .foo : {*(.foo.*)} :all \ +# RUN: .data : {*(.data.*)} :all}" > %t.script + +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x10000000 +# CHECK-NEXT: PhysicalAddress: 0x10000000 +# CHECK-NEXT: FileSize: 521 +# CHECK-NEXT: MemSize: 521 +# CHECK-NEXT: Flags [ (0x7) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] + +.global _start +_start: + nop + +.section .foo.1,"a" +foo1: + .long 0 + +.section .foo.2,"a" +foo2: + .long 0