Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -855,6 +855,15 @@ return nullptr; } +static uint64_t computeBase(uint64_t Min) { + // If there is no SECTIONS or if the linkerscript is explicit about program + // headers, do our best to allocate them. + if (!Script->HasSectionsCommand || Script->hasPhdrsCommands()) + return 0; + // Otherwise only allocate program headers if that would not add a page. + return alignDown(Min, Config->MaxPageSize); +} + // Try to find an address for the file and program headers output sections, // which were unconditionally added to the first PT_LOAD segment earlier. // @@ -879,10 +888,7 @@ PhdrEntry *FirstPTLoad = *It; uint64_t HeaderSize = getHeaderSize(); - // When linker script with SECTIONS is being used, don't output headers - // unless there's a space for them. - uint64_t Base = HasSectionsCommand ? alignDown(Min, Config->MaxPageSize) : 0; - if (HeaderSize <= Min - Base || Script->hasPhdrsCommands()) { + if (HeaderSize <= Min - computeBase(Min)) { Min = alignDown(Min - HeaderSize, Config->MaxPageSize); Out::ElfHeader->Addr = Min; Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; Index: test/ELF/linkerscript/header-phdr2.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/header-phdr2.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; } \ +# RUN: SECTIONS { .text : { *(.text) } : foobar }" > %t.script +# RUN: ld.lld --script %t.script %t.o -o %t +# RUN: llvm-readelf -l %t | FileCheck %s + +# CHECK-NOT: PT_LOAD +# CHECK: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000001 0x000001 R E 0x1000 +# CHECK-NOT: PT_LOAD + + .global _start +_start: + retq