Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -215,14 +215,20 @@ } } +static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) { + bool RO = (Kind == ConstraintKind::ReadOnly); + bool RW = (Kind == ConstraintKind::ReadWrite); + bool Writable = Flags & SHF_WRITE; + return !((RO && Writable) || (RW && !Writable)); +} + template static bool matchConstraints(ArrayRef *> Sections, ConstraintKind Kind) { - 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); + if (Kind == ConstraintKind::NoConstraint) + return true; + return llvm::all_of(Sections, [=](InputSectionBase *Sec) { + return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind); }); } @@ -330,6 +336,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 +382,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: lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s =================================================================== --- lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s +++ lld/trunk/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