Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -20,6 +20,7 @@ #include "OutputSections.h" #include "ScriptParser.h" #include "SymbolTable.h" +#include "Target.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ELF.h" #include "llvm/Support/FileSystem.h" @@ -33,6 +34,7 @@ using namespace lld; using namespace lld::elf; +extern lld::elf::TargetInfo *Target; ScriptConfiguration *elf::ScriptConfig; static bool matchStr(StringRef S, StringRef T); @@ -222,11 +224,15 @@ // Assign addresses as instructed by linker script SECTIONS sub-commands. Dot = Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); + uintX_t firstSecOff = Dot; + uintX_t BaseVA = 0; uintX_t ThreadBssOffset = 0; for (SectionsCommand &Cmd : Opt.Commands) { if (Cmd.Kind == ExprKind) { Dot = evalExpr(Cmd.Expr, Dot); + if (BaseVA == 0 && Dot >= firstSecOff) + BaseVA = alignDown(Dot - firstSecOff, Target->PageSize); continue; } @@ -253,6 +259,9 @@ } } } + + Out::ElfHeader->setVA(BaseVA); + Out::ProgramHeaders->setVA(Out::ElfHeader->getSize() + BaseVA); } template Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -66,7 +66,7 @@ void assignAddresses(); void assignFileOffsets(); void setPhdrs(); - void fixHeaders(); + void fixHeaders(); void fixSectionAlignments(); void fixAbsoluteSymbols(); void openFile(); @@ -1183,9 +1183,10 @@ // Assign file offsets to output sections. template void Writer::assignFileOffsets() { - uintX_t Off = + uintX_t Off = ScriptConfig->DoLayout && OutputSections.size() ? + OutputSections.front()->getVA() - Out::ElfHeader->getVA() : Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); - + 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 +