summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Leviant <evgeny.leviant@gmail.com>2016-08-04 08:20:23 +0000
committerEugene Leviant <evgeny.leviant@gmail.com>2016-08-04 08:20:23 +0000
commitc7611fc567eb92e9ad571eab05c606a903b0de68 (patch)
tree7ea3a41761830b559a6fe59674755f8cdbb4332b
parent0c07f0cb0b467ed1687880785125b9bdbfa25a7a (diff)
downloadbcm5719-llvm-c7611fc567eb92e9ad571eab05c606a903b0de68.tar.gz
bcm5719-llvm-c7611fc567eb92e9ad571eab05c606a903b0de68.zip
[ELF] Linkerscript: remove repeated sections in filter()
llvm-svn: 277703
-rw-r--r--lld/ELF/LinkerScript.cpp24
-rw-r--r--lld/test/ELF/linkerscript/linkerscript-sections-constraint.s18
2 files changed, 28 insertions, 14 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index e58b3be0277..08d0b953d7a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -192,6 +192,11 @@ void LinkerScript<ELFT>::createSections(
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.
template <class ELFT> void LinkerScript<ELFT>::filter() {
// 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)
continue;
- auto It = llvm::find_if(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
- return S->getName() == Cmd->Name;
- });
- 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);
+ removeElementsIf(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
+ bool Writable = (S->getFlags() & SHF_WRITE);
+ bool RO = (Cmd->Constraint == ConstraintKind::ReadOnly);
+ bool RW = (Cmd->Constraint == ConstraintKind::ReadWrite);
- if ((RO && Writable) || (RW && !Writable))
- OutputSections->erase(It);
+ return S->getName() == Cmd->Name &&
+ ((RO && Writable) || (RW && !Writable));
+ });
}
}
diff --git a/lld/test/ELF/linkerscript/linkerscript-sections-constraint.s b/lld/test/ELF/linkerscript/linkerscript-sections-constraint.s
index 84711e7bff8..cceba92adcc 100644
--- a/lld/test/ELF/linkerscript/linkerscript-sections-constraint.s
+++ b/lld/test/ELF/linkerscript/linkerscript-sections-constraint.s
@@ -9,8 +9,8 @@
# BASE: Sections:
# BASE-NEXT: Idx Name Size Address Type
# BASE-NEXT: 0 00000000 0000000000000000
-# BASE-NEXT: 1 .writable 00000004 0000000000000190 DATA
-# BASE-NEXT: 2 .readable 00000004 0000000000000194 DATA
+# BASE-NEXT: 1 .writable 00000004 0000000000000200 DATA
+# BASE-NEXT: 2 .readable 00000004 0000000000000204 DATA
# RUN: echo "SECTIONS { \
# RUN: .writable : ONLY_IF_RO { *(.writable) } \
@@ -22,6 +22,14 @@
# NOSECTIONS-NOT: .writable
# 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
_start:
nop
@@ -33,3 +41,9 @@ writable:
.section .readable, "a"
readable:
.long 2
+
+.section .foo.1, "awx"
+ .long 0
+
+.section .foo.2, "aw"
+ .long 0
OpenPOWER on IntegriCloud