Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -216,13 +216,22 @@ } template -static bool matchConstraints(ArrayRef *> Sections, - ConstraintKind Kind) { +static bool checkConstraint(typename ELFT::uint Flags, ConstraintKind Kind) { + if (Kind == ConstraintKind::NoConstraint) + return true; bool RO = (Kind == ConstraintKind::ReadOnly); bool RW = (Kind == ConstraintKind::ReadWrite); - return !llvm::any_of(Sections, [=](InputSectionBase *Sec) { - bool Writable = Sec->getSectionHdr()->sh_flags & SHF_WRITE; - return (RO && Writable) || (RW && !Writable); + bool Writable = Flags & SHF_WRITE; + return (RO && !Writable) || (RW && Writable); +} + +template +static bool matchConstraints(ArrayRef *> Sections, + ConstraintKind Kind) { + if (Kind == ConstraintKind::NoConstraint) + return true; + return llvm::all_of(Sections, [=](InputSectionBase *Sec) { + return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); }); } @@ -330,6 +339,19 @@ } } +template +static OutputSectionBase * +findSection(OutputSectionCommand &Cmd, + ArrayRef *> Sections) { + for (OutputSectionBase *Sec : Sections) { + if (Sec->getName() != Cmd.Name) + continue; + if (checkConstraint(Sec->getFlags(), Cmd.Constraint)) + return Sec; + } + return nullptr; +} + template void LinkerScript::assignAddresses() { // Orphan sections are sections present in the input files which // are not explicitly placed into the output file by the linker script. @@ -363,12 +385,9 @@ } auto *Cmd = cast(Base.get()); - auto I = llvm::find_if(*OutputSections, [&](OutputSectionBase *S) { - return S->getName() == Cmd->Name; - }); - if (I == OutputSections->end()) + OutputSectionBase *Sec = findSection(*Cmd, *OutputSections); + if (!Sec) continue; - OutputSectionBase *Sec = *I; if (Cmd->AddrExpr) Dot = Cmd->AddrExpr(Dot); Index: test/ELF/linkerscript/linkerscript-multi-sections-constraint.s =================================================================== --- test/ELF/linkerscript/linkerscript-multi-sections-constraint.s +++ test/ELF/linkerscript/linkerscript-multi-sections-constraint.s @@ -15,6 +15,21 @@ # CHECK-NEXT: 4 .shstrtab 00000026 0000000000000000 # CHECK-NEXT: 5 .strtab 00000008 0000000000000000 +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1000; .aaa : ONLY_IF_RW { *(.aaa.*) } \ +# RUN: . = 0x2000; .aaa : ONLY_IF_RO { *(.aaa.*) } } " > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %t +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV + +# REV: Sections: +# REV-NEXT: Idx Name Size Address Type +# REV-NEXT: 0 00000000 0000000000000000 +# REV-NEXT: 1 .aaa 00000010 0000000000001000 DATA +# REV-NEXT: 2 .text 00000001 0000000000002000 TEXT DATA +# REV-NEXT: 3 .symtab 00000030 0000000000000000 +# REV-NEXT: 4 .shstrtab 00000026 0000000000000000 +# REV-NEXT: 5 .strtab 00000008 0000000000000000 + .global _start _start: nop