<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Sep 16, 2016 at 10:42 AM, George Rimar via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: grimar<br>
Date: Fri Sep 16 12:42:10 2016<br>
New Revision: 281754<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=281754&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=281754&view=rev</a><br>
Log:<br>
Recommit r281721 "[ELF] - Linkerscript: implement EXCLUDE_FILE in the middle of a input section description."<br>
<br>
With fix for 2 bots. Details about the fix performed is on a review page.<br>
<br>
Initial commit message:<br>
This is PR30387:<br>
<br>
>From PR description:<br>
We fail to parse<br>
<br>
SECTIONS<br>
{<br>
  foo :<br>
  {<br>
    *(sec0 EXCLUDE_FILE (zed1.o) sec1  EXCLUDE_FILE (zed2.o) sec2 )<br>
  }<br>
}<br>
The semantics according to bfd are:<br>
<br>
Include sec1 from every file but zed1.o<br>
Include sec2 from every file but zed2.o<br>
Include sec0 from every file<br>
<br>
Patch implements the support.<br>
<br>
Differential revision: <a href="https://reviews.llvm.org/D24650" rel="noreferrer" target="_blank">https://reviews.llvm.org/D2465<wbr>0</a><br>
<br>
Added:<br>
    lld/trunk/test/ELF/linkerscrip<wbr>t/Inputs/exclude-multiple1.s<br>
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscrip<wbr>t/Inputs/exclude-multiple1.s<br>
    lld/trunk/test/ELF/linkerscrip<wbr>t/Inputs/exclude-multiple2.s<br>
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscrip<wbr>t/Inputs/exclude-multiple2.s<br>
    lld/trunk/test/ELF/linkerscrip<wbr>t/exclude-multiple.s<br>
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscrip<wbr>t/exclude-multiple.s<br>
Modified:<br>
    lld/trunk/ELF/LinkerScript.cpp<br>
    lld/trunk/ELF/LinkerScript.h<br>
<br>
Modified: lld/trunk/ELF/LinkerScript.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=281754&r1=281753&r2=281754&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/LinkerScri<wbr>pt.cpp?rev=281754&r1=281753&<wbr>r2=281754&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LinkerScript.cpp (original)<br>
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep 16 12:42:10 2016<br>
@@ -109,10 +109,10 @@ bool LinkerScript<ELFT>::shouldKeep<wbr>(Inpu<br>
   return false;<br>
 }<br>
<br>
-static bool fileMatches(const InputSectionDescription *Desc,<br>
-                        StringRef Filename) {<br>
-  return const_cast<Regex &>(Desc->FileRe).match(Filenam<wbr>e) &&<br>
-         !const_cast<Regex &>(Desc->ExcludedFileRe).match<wbr>(Filename);<br>
+static bool fileMatches(const llvm::Regex &FileRe,<br>
+                        const llvm::Regex &ExcludedFileRe, StringRef Filename) {<br>
+  return const_cast<Regex &>(FileRe).match(Filename) &&<br>
+         !const_cast<Regex &>(ExcludedFileRe).match(Filen<wbr>ame);<br>
 }<br>
<br>
 static bool comparePriority(InputSectionDa<wbr>ta *A, InputSectionData *B) {<br>
@@ -161,16 +161,19 @@ static bool matchConstraints(ArrayRef<In<br>
 template <class ELFT><br>
 void LinkerScript<ELFT>::computeInp<wbr>utSections(InputSectionDescrip<wbr>tion *I,<br>
                                               ConstraintKind Constraint) {<br>
-  const Regex &Re = I->SectionRe;<br>
-  for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFile<wbr>s())<br>
-    if (fileMatches(I, sys::path::filename(F->getName<wbr>())))<br>
-      for (InputSectionBase<ELFT> *S : F->getSections())<br>
-        if (!isDiscarded(S) && !S->OutSec &&<br>
-            const_cast<Regex &>(Re).match(S->Name))<br>
-          I->Sections.push_back(S);<br>
+  for (const std::pair<llvm::Regex, llvm::Regex> &V : I->SectionsVec) {<br>
+    for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFile<wbr>s()) {<br>
+      if (fileMatches(I->FileRe, V.first, sys::path::filename(F->getName<wbr>()))) {<br>
+        Regex &Re = const_cast<Regex &>(V.second);<br>
+        for (InputSectionBase<ELFT> *S : F->getSections())<br>
+          if (!isDiscarded(S) && !S->OutSec && Re.match(S->Name))<br>
+            I->Sections.push_back(S);<br>
<br>
-  if (const_cast<Regex &>(Re).match("COMMON"))<br>
-    I->Sections.push_back(CommonIn<wbr>putSection<ELFT>::X);<br>
+        if (Re.match("COMMON"))<br>
+          I->Sections.push_back(CommonIn<wbr>putSection<ELFT>::X);<br>
+      }<br>
+    }<br>
+  }<br>
<br>
   if (!matchConstraints<ELFT>(I->Se<wbr>ctions, Constraint)) {<br>
     I->Sections.clear();<br>
@@ -698,6 +701,7 @@ private:<br>
   std::vector<StringRef> readOutputSectionPhdrs();<br>
   InputSectionDescription *readInputSectionDescription(S<wbr>tringRef Tok);<br>
   Regex readFilePatterns();<br>
+  void readSectionExcludes(InputSecti<wbr>onDescription *Cmd);<br>
   InputSectionDescription *readInputSectionRules(StringR<wbr>ef FilePattern);<br>
   unsigned readPhdrType();<br>
   SortKind readSortKind();<br>
@@ -991,17 +995,41 @@ SortKind ScriptParser::readSortKind() {<br>
   return SortNone;<br>
 }<br>
<br>
+// Method reads a list of sequence of excluded files and section globs given in<br>
+// a following form: ((EXCLUDE_FILE(file_pattern+))<wbr>? section_pattern+)+<br>
+// Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)<br>
+void ScriptParser::readSectionExclu<wbr>des(InputSectionDescription *Cmd) {<br>
+  llvm::Regex ExcludeFileRe;<br>
+  std::vector<StringRef> V;<br>
+<br>
+  while (!Error) {<br>
+    if (skip(")")) {<br>
+      Cmd->SectionsVec.push_back(<br>
+          {std::move(ExcludeFileRe), compileGlobPatterns(V)});<br>
+      return;<br>
+    }<br>
+<br>
+    if (skip("EXCLUDE_FILE")) {<br>
+      if (!V.empty()) {<br>
+        Cmd->SectionsVec.push_back(<br>
+            {std::move(ExcludeFileRe), compileGlobPatterns(V)});<br>
+        V.clear();<br>
+      }<br>
+<br>
+      expect("(");<br>
+      ExcludeFileRe = readFilePatterns();<br>
+      continue;<br>
+    }<br>
+<br>
+    V.push_back(next());<br>
+  }<br>
+}<br>
+<br>
 InputSectionDescription *<br>
 ScriptParser::readInputSectio<wbr>nRules(StringRef FilePattern) {<br>
   auto *Cmd = new InputSectionDescription(FilePa<wbr>ttern);<br>
   expect("(");<br>
<br>
-  // Read EXCLUDE_FILE().<br>
-  if (skip("EXCLUDE_FILE")) {<br>
-    expect("(");<br>
-    Cmd->ExcludedFileRe = readFilePatterns();<br>
-  }<br>
-<br>
   // Read SORT().<br>
   if (SortKind K1 = readSortKind()) {<br>
     Cmd->SortOuter = K1;<br>
@@ -1009,16 +1037,16 @@ ScriptParser::readInputSection<wbr>Rules(Stri<br>
     if (SortKind K2 = readSortKind()) {<br>
       Cmd->SortInner = K2;<br>
       expect("(");<br>
-      Cmd->SectionRe = readFilePatterns();<br>
+      Cmd->SectionsVec.push_back({ll<wbr>vm::Regex(), readFilePatterns()});<br>
       expect(")");<br>
     } else {<br>
-      Cmd->SectionRe = readFilePatterns();<br>
+      Cmd->SectionsVec.push_back({ll<wbr>vm::Regex(), readFilePatterns()});<br>
     }<br>
     expect(")");<br>
     return Cmd;<br>
   }<br>
<br>
-  Cmd->SectionRe = readFilePatterns();<br>
+  readSectionExcludes(Cmd);<br>
   return Cmd;<br>
 }<br>
<br>
@@ -1031,7 +1059,8 @@ ScriptParser::readInputSection<wbr>Descriptio<br>
     StringRef FilePattern = next();<br>
     InputSectionDescription *Cmd = readInputSectionRules(FilePatt<wbr>ern);<br>
     expect(")");<br>
-    Opt.KeptSections.push_back(&Cm<wbr>d->SectionRe);<br>
+    for (std::pair<llvm::Regex, llvm::Regex> &Regex : Cmd->SectionsVec)<br>
+      Opt.KeptSections.push_back(&Re<wbr>gex.second);<br>
     return Cmd;<br>
   }<br>
   return readInputSectionRules(Tok);<br>
<br>
Modified: lld/trunk/ELF/LinkerScript.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=281754&r1=281753&r2=281754&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/ELF/LinkerScri<wbr>pt.h?rev=281754&r1=281753&r2=<wbr>281754&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LinkerScript.h (original)<br>
+++ lld/trunk/ELF/LinkerScript.h Fri Sep 16 12:42:10 2016<br>
@@ -20,6 +20,7 @@<br>
 #include "llvm/Support/MemoryBuffer.h"<br>
 #include "llvm/Support/Regex.h"<br>
 #include <functional><br>
+#include <list><br>
<br>
 namespace lld {<br>
 namespace elf {<br>
@@ -106,8 +107,8 @@ struct InputSectionDescription : BaseCom<br>
   llvm::Regex FileRe;<br>
   SortKind SortOuter = SortNone;<br>
   SortKind SortInner = SortNone;<br>
-  llvm::Regex ExcludedFileRe;<br>
-  llvm::Regex SectionRe;<br>
+  // Pairs of section regex and files excluded.<br>
+  std::list<std::pair<llvm::Rege<wbr>x, llvm::Regex>> SectionsVec;<br>
   std::vector<InputSectionData *> Sections;<br>
 };<br></blockquote><div><br></div><div>I didn't read the entire patch yet, but why did you use <list>? It is a doubly-linked list and slower than the vector, so you don't want to use it unless you really want doubly-linked lists.</div></div></div></div>