Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -682,6 +682,7 @@ // Process PHDRS and FILEHDR keywords because they are not // real output sections and cannot be added in the following loop. + std::vector DefPhdrIds; for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) { Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags); PhdrEntry &Phdr = Ret.back(); @@ -695,16 +696,20 @@ Phdr.H.p_paddr = Cmd.LMAExpr(0); Phdr.HasLMA = true; } + + if (DefPhdrIds.empty() && Phdr.H.p_type == PT_LOAD) + DefPhdrIds.push_back(Ret.size() - 1); } // Add output sections to program headers. - PhdrEntry *Load = nullptr; - uintX_t Flags = PF_R; for (OutputSectionBase *Sec : *OutputSections) { if (!(Sec->getFlags() & SHF_ALLOC)) break; std::vector PhdrIds = getPhdrIndices(Sec->getName()); + if (PhdrIds.empty()) + PhdrIds = std::move(DefPhdrIds); + if (!PhdrIds.empty()) { // Assign headers specified by linker script for (size_t Id : PhdrIds) { @@ -712,16 +717,8 @@ if (Opt.PhdrsCommands[Id].Flags == UINT_MAX) Ret[Id].H.p_flags |= Sec->getPhdrFlags(); } - } else { - // If we have no load segment or flags've changed then we want new load - // segment. - uintX_t NewFlags = Sec->getPhdrFlags(); - if (Load == nullptr || Flags != NewFlags) { - Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags); - Flags = NewFlags; - } - Load->add(Sec); } + DefPhdrIds = std::move(PhdrIds); } return Ret; } Index: test/ELF/linkerscript/openbsd-randomize.s =================================================================== --- test/ELF/linkerscript/openbsd-randomize.s +++ test/ELF/linkerscript/openbsd-randomize.s @@ -1,15 +1,16 @@ # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o # RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \ # RUN: SECTIONS { . = SIZEOF_HEADERS; \ +# RUN: .text : { *(.text) } \ # RUN: .openbsd.randomdata : { *(.openbsd.randomdata) } : 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_RANDOMIZE (0x65A3DBE6) -# CHECK-NEXT: Offset: 0x94 -# CHECK-NEXT: VirtualAddress: 0x94 -# CHECK-NEXT: PhysicalAddress: 0x94 +# CHECK-NEXT: Offset: 0x74 +# CHECK-NEXT: VirtualAddress: 0x74 +# CHECK-NEXT: PhysicalAddress: 0x74 # CHECK-NEXT: FileSize: 8 # CHECK-NEXT: MemSize: 8 # CHECK-NEXT: Flags [ (0x4) Index: test/ELF/linkerscript/phdrs-flags.s =================================================================== --- test/ELF/linkerscript/phdrs-flags.s +++ test/ELF/linkerscript/phdrs-flags.s @@ -6,9 +6,18 @@ # 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 + +# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (0x1);} \ +# RUN: SECTIONS { \ +# RUN: . = 0x10000200; \ +# RUN: .text : {*(.text*)} :all \ +# RUN: .foo : {*(.foo.*)} \ +# RUN: .data : {*(.data.*)} }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s + # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) @@ -22,6 +31,20 @@ # CHECK-NEXT: PF_X (0x1) # CHECK-NEXT: ] +# DEFHDR: ProgramHeaders [ +# DEFHDR-NEXT: ProgramHeader { +# DEFHDR-NEXT: Type: PT_LOAD (0x1) +# DEFHDR-NEXT: Offset: 0x0 +# DEFHDR-NEXT: VirtualAddress: 0x10000000 +# DEFHDR-NEXT: PhysicalAddress: 0x10000000 +# DEFHDR-NEXT: FileSize: 521 +# DEFHDR-NEXT: MemSize: 521 +# DEFHDR-NEXT: Flags [ (0x1) +# DEFHDR-NEXT: PF_X (0x1) +# DEFHDR-NEXT: ] +# DEFHDR-NEXT: Alignment: 4096 +# DEFHDR-NEXT: } + .global _start _start: nop Index: test/ELF/linkerscript/phdrs.s =================================================================== --- test/ELF/linkerscript/phdrs.s +++ test/ELF/linkerscript/phdrs.s @@ -19,6 +19,15 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=AT %s +# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS ;} \ +# RUN: SECTIONS { \ +# RUN: . = 0x10000200; \ +# RUN: .text : {*(.text*)} :all \ +# RUN: .foo : {*(.foo.*)} \ +# RUN: .data : {*(.data.*)} }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s + # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) @@ -70,6 +79,20 @@ # INT-PHDRS-NEXT: } # INT-PHDRS-NEXT: ] +# DEFHDR: ProgramHeaders [ +# DEFHDR-NEXT: ProgramHeader { +# DEFHDR-NEXT: Type: PT_LOAD (0x1) +# DEFHDR-NEXT: Offset: 0x0 +# DEFHDR-NEXT: VirtualAddress: 0x10000000 +# DEFHDR-NEXT: PhysicalAddress: 0x10000000 +# DEFHDR-NEXT: FileSize: 521 +# DEFHDR-NEXT: MemSize: 521 +# DEFHDR-NEXT: Flags [ (0x7) +# DEFHDR-NEXT: PF_R (0x4) +# DEFHDR-NEXT: PF_W (0x2) +# DEFHDR-NEXT: PF_X (0x1) +# DEFHDR-NEXT: ] + .global _start _start: nop