Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -245,14 +245,14 @@ if (V.empty()) continue; - OutputSectionBase *OutSec; - bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name); - if (IsNew) - OutputSections->push_back(OutSec); - - uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; for (InputSectionBase *Sec : V) { + OutputSectionBase *OutSec; + bool IsNew; + std::tie(OutSec, IsNew) = Factory.create(Sec, Cmd->Name); + if (IsNew) + OutputSections->push_back(OutSec); + + uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; if (Subalign) Sec->Alignment = Subalign; OutSec->addSection(Sec); @@ -362,16 +362,17 @@ } template -static OutputSectionBase * +static std::vector *> findSection(OutputSectionCommand &Cmd, ArrayRef *> Sections) { + std::vector *> Out; for (OutputSectionBase *Sec : Sections) { if (Sec->getName() != Cmd.Name) continue; if (checkConstraint(Sec->getFlags(), Cmd.Constraint)) - return Sec; + Out.push_back(Sec); } - return nullptr; + return Out; } template void LinkerScript::assignAddresses() { @@ -407,35 +408,34 @@ } auto *Cmd = cast(Base.get()); - OutputSectionBase *Sec = findSection(*Cmd, *OutputSections); - if (!Sec) - continue; - - if (Cmd->AddrExpr) - Dot = Cmd->AddrExpr(Dot); - - if (Cmd->AlignExpr) - Sec->updateAlignment(Cmd->AlignExpr(Dot)); + for (OutputSectionBase *Sec : + findSection(*Cmd, *OutputSections)) { + if (Cmd->AddrExpr) + Dot = Cmd->AddrExpr(Dot); + + if (Cmd->AlignExpr) + Sec->updateAlignment(Cmd->AlignExpr(Dot)); + + if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { + uintX_t TVA = Dot + ThreadBssOffset; + TVA = alignTo(TVA, Sec->getAlignment()); + Sec->setVA(TVA); + assignOffsets(Cmd, Sec); + ThreadBssOffset = TVA - Dot + Sec->getSize(); + continue; + } - if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { - uintX_t TVA = Dot + ThreadBssOffset; - TVA = alignTo(TVA, Sec->getAlignment()); - Sec->setVA(TVA); - assignOffsets(Cmd, Sec); - ThreadBssOffset = TVA - Dot + Sec->getSize(); - continue; - } + if (!(Sec->getFlags() & SHF_ALLOC)) { + assignOffsets(Cmd, Sec); + continue; + } - if (!(Sec->getFlags() & SHF_ALLOC)) { + Dot = alignTo(Dot, Sec->getAlignment()); + Sec->setVA(Dot); assignOffsets(Cmd, Sec); - continue; + MinVA = std::min(MinVA, Dot); + Dot += Sec->getSize(); } - - Dot = alignTo(Dot, Sec->getAlignment()); - Sec->setVA(Dot); - assignOffsets(Cmd, Sec); - MinVA = std::min(MinVA, Dot); - Dot += Sec->getSize(); } // ELF and Program headers need to be right before the first section in Index: test/ELF/linkerscript/linkerscript-merge-sections.s =================================================================== --- test/ELF/linkerscript/linkerscript-merge-sections.s +++ test/ELF/linkerscript/linkerscript-merge-sections.s @@ -1,28 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t - -# RUN: echo "SECTIONS { .foo : { *(.foo.*) } }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -s %t1 | FileCheck %s -# CHECK: Contents of section .foo: -# CHECK-NEXT: 0158 01000000 02000000 00000000 73686f72 ............shor -# CHECK-NEXT: 0168 7420756e 7369676e 65642069 6e7400 t unsigned int. - -.global _start -_start: - nop - -.section .foo.1, "aw" -writable: - .long 1 - -.section .foo.2, "aM",@progbits,1 -readable: - .long 2 - -.section .foo.3, "awx" - .long 0 - -.section .foo.4, "MS",@progbits,1 -.LASF2: - .string "short unsigned int" Index: test/ELF/linkerscript/linkerscript-phdrs.s =================================================================== --- test/ELF/linkerscript/linkerscript-phdrs.s +++ test/ELF/linkerscript/linkerscript-phdrs.s @@ -17,8 +17,9 @@ # CHECK-NEXT: PhysicalAddress: 0x10000000 # CHECK-NEXT: FileSize: 521 # CHECK-NEXT: MemSize: 521 -# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: Flags [ (0x7) # CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) # CHECK-NEXT: PF_X (0x1) # CHECK-NEXT: ] Index: test/ELF/linkerscript/linkerscript-repsection-va.s =================================================================== --- test/ELF/linkerscript/linkerscript-repsection-va.s +++ test/ELF/linkerscript/linkerscript-repsection-va.s @@ -7,8 +7,9 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address Type # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK-NEXT: 1 .foo 00000008 0000000000000120 DATA -# CHECK-NEXT: 2 .text 00000001 0000000000000128 TEXT DATA +# CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA +# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA +# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA .global _start _start: