Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -67,6 +67,7 @@ void assignFileOffsets(); void setPhdrs(); void fixHeaders(); + void fixHeaders(uintX_t BaseVA); void fixSectionAlignments(); void fixAbsoluteSymbols(); void openFile(); @@ -1129,8 +1130,7 @@ // We should set file offsets and VAs for elf header and program headers // sections. These are special, we do not include them into output sections // list, but have them to simplify the code. -template void Writer::fixHeaders() { - uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Target->getVAStart(); +template void Writer::fixHeaders(uintX_t BaseVA) { Out::ElfHeader->setVA(BaseVA); Out::ElfHeader->setFileOffset(0); uintX_t Off = Out::ElfHeader->getSize(); @@ -1138,6 +1138,11 @@ Out::ProgramHeaders->setFileOffset(Off); } +template void Writer::fixHeaders() { + uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Target->getVAStart(); + fixHeaders(BaseVA); +} + // Assign VAs (addresses at run-time) to output sections. template void Writer::assignAddresses() { uintX_t VA = Target->getVAStart() + Out::ElfHeader->getSize() + @@ -1186,6 +1191,18 @@ uintX_t Off = Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); + if (ScriptConfig->DoLayout) { + uintX_t BaseVA = Target->getVAStart(); + if (!OutputSections.empty()) { + // If we have any sections to output then calculate base VA, which + // should be page aligned + OutputSectionBase *First = OutputSections.front(); + BaseVA = alignDown(First->getVA() - Off, Target->PageSize); + Off = First->getVA() - BaseVA; + } + fixHeaders(BaseVA); + } + for (OutputSectionBase *Sec : OutputSections) { if (Sec->getType() == SHT_NOBITS) { Sec->setFileOffset(Off); Index: test/ELF/linkerscript-phdr-check.s =================================================================== --- test/ELF/linkerscript-phdr-check.s +++ test/ELF/linkerscript-phdr-check.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %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_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0xFFFF040 + +.global _start +_start: + nop +