Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -45,11 +45,6 @@ OutputSection *LastSec = nullptr; bool HasLMA = false; - // True if one of the sections in this program header has a LMA specified via - // linker script: AT(addr). We never allow 2 or more sections with LMA in the - // same program header. - bool ASectionHasLMA = false; - uint64_t LMAOffset = 0; }; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -821,8 +821,6 @@ p_align = std::max(p_align, Sec->Alignment); if (p_type == PT_LOAD) Sec->PtLoad = this; - if (Sec->LMAExpr) - ASectionHasLMA = true; } // The beginning and the ending of .rel[a].plt section are marked @@ -1654,6 +1652,7 @@ Load->add(Out::ElfHeader); Load->add(Out::ProgramHeaders); + bool FirstLoadSection = true; for (OutputSection *Sec : OutputSections) { if (!(Sec->Flags & SHF_ALLOC)) break; @@ -1666,7 +1665,7 @@ // different flags or is loaded at a discontiguous address using AT linker // script command. uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); - if ((Sec->LMAExpr && Load->ASectionHasLMA) || + if ((Sec->LMAExpr && !FirstLoadSection) || Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { Load = AddHdr(PT_LOAD, NewFlags); @@ -1674,6 +1673,7 @@ } Load->add(Sec); + FirstLoadSection = false; } // Add a TLS segment if any. Index: test/ELF/linkerscript/at5.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/at5.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1000; \ +# RUN: .aaa : { *(.aaa) } \ +# RUN: .bbb : AT(0x2008) { *(.bbb) } \ +# RUN: .ccc : { *(.ccc) } \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-readobj -program-headers %t2 | tee %t2.log | FileCheck %s + +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1008 +# CHECK-NEXT: VirtualAddress: 0x1008 +# CHECK-NEXT: PhysicalAddress: 0x2008 +# CHECK-NEXT: FileSize: 17 +# CHECK-NEXT: MemSize: 17 + +.global _start +_start: + nop + +.section .aaa, "a" +.quad 0 + +.section .bbb, "a" +.quad 0 + +.section .ccc, "a" +.quad 0