[ELF] Linkerscript: remove repeated sections in filter()

llvm-svn: 277703
This commit is contained in:
Eugene Leviant 2016-08-04 08:20:23 +00:00
parent 0c07f0cb0b
commit c7611fc567
2 changed files with 28 additions and 14 deletions

View File

@ -192,6 +192,11 @@ void LinkerScript<ELFT>::createSections(
filter(); filter();
} }
template <class R, class T>
static inline void removeElementsIf(R &Range, const T &Pred) {
Range.erase(std::remove_if(Range.begin(), Range.end(), Pred), Range.end());
}
// Process ONLY_IF_RO and ONLY_IF_RW. // Process ONLY_IF_RO and ONLY_IF_RW.
template <class ELFT> void LinkerScript<ELFT>::filter() { template <class ELFT> void LinkerScript<ELFT>::filter() {
// In this loop, we remove output sections if they don't satisfy // In this loop, we remove output sections if they don't satisfy
@ -204,19 +209,14 @@ template <class ELFT> void LinkerScript<ELFT>::filter() {
if (Cmd->Constraint == ConstraintKind::NoConstraint) if (Cmd->Constraint == ConstraintKind::NoConstraint)
continue; continue;
auto It = llvm::find_if(*OutputSections, [&](OutputSectionBase<ELFT> *S) { removeElementsIf(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
return S->getName() == Cmd->Name; bool Writable = (S->getFlags() & SHF_WRITE);
bool RO = (Cmd->Constraint == ConstraintKind::ReadOnly);
bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite);
return S->getName() == Cmd->Name &&
((RO && Writable) || (RW && !Writable));
}); });
if (It == OutputSections->end())
continue;
OutputSectionBase<ELFT> *Sec = *It;
bool Writable = (Sec->getFlags() & SHF_WRITE);
bool RO = (Cmd->Constraint == ConstraintKind::ReadOnly);
bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite);
if ((RO && Writable) || (RW && !Writable))
OutputSections->erase(It);
} }
} }

View File

@ -9,8 +9,8 @@
# BASE: Sections: # BASE: Sections:
# BASE-NEXT: Idx Name Size Address Type # BASE-NEXT: Idx Name Size Address Type
# BASE-NEXT: 0 00000000 0000000000000000 # BASE-NEXT: 0 00000000 0000000000000000
# BASE-NEXT: 1 .writable 00000004 0000000000000190 DATA # BASE-NEXT: 1 .writable 00000004 0000000000000200 DATA
# BASE-NEXT: 2 .readable 00000004 0000000000000194 DATA # BASE-NEXT: 2 .readable 00000004 0000000000000204 DATA
# RUN: echo "SECTIONS { \ # RUN: echo "SECTIONS { \
# RUN: .writable : ONLY_IF_RO { *(.writable) } \ # RUN: .writable : ONLY_IF_RO { *(.writable) } \
@ -22,6 +22,14 @@
# NOSECTIONS-NOT: .writable # NOSECTIONS-NOT: .writable
# NOSECTIONS-NOT: .readable # NOSECTIONS-NOT: .readable
# RUN: echo "SECTIONS { \
# RUN: .foo : ONLY_IF_RO { *(.foo.*) }}" > %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -section-headers %t1 | \
# RUN: FileCheck -check-prefix=NOSECTIONS2 %s
# NOSECTIONS2: Sections:
# NOSECTIONS2-NOT: .foo
.global _start .global _start
_start: _start:
nop nop
@ -33,3 +41,9 @@ writable:
.section .readable, "a" .section .readable, "a"
readable: readable:
.long 2 .long 2
.section .foo.1, "awx"
.long 0
.section .foo.2, "aw"
.long 0