[PATCH] D23122: [ELF] Linkerscript: remove repeated sections in LinkerScript<ELFT>::filter

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 3 07:07:16 PDT 2016


evgeny777 created this revision.
evgeny777 added a reviewer: ruiu.
evgeny777 added subscribers: grimar, emaste, davide, ikudrin, llvm-commits.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.

Currently we can have more than one output section with the same name. The LinkerScript filter() method removes only first section found in name lookup.

Repository:
  rL LLVM

https://reviews.llvm.org/D23122

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/linkerscript-sections-constraint.s

Index: test/ELF/linkerscript/linkerscript-sections-constraint.s
===================================================================
--- test/ELF/linkerscript/linkerscript-sections-constraint.s
+++ 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 @@
 .section .readable, "a"
 readable:
  .long 2
+
+.section .foo.1, "awx"
+ .long 0
+
+.section .foo.2, "aw"
+ .long 0
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -190,6 +190,11 @@
   filter();
 }
 
+template <class R, class T>
+static inline void removeElements(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
@@ -202,19 +207,14 @@
     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);
+    removeElements(*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));
+    });
   }
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23122.66662.patch
Type: text/x-patch
Size: 2746 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160803/bc8f3c9b/attachment.bin>


More information about the llvm-commits mailing list