[lld] r281754 - Recommit r281721 "[ELF] - Linkerscript: implement EXCLUDE_FILE in the middle of a input section description."

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 16 10:42:11 PDT 2016


Author: grimar
Date: Fri Sep 16 12:42:10 2016
New Revision: 281754

URL: http://llvm.org/viewvc/llvm-project?rev=281754&view=rev
Log:
Recommit r281721 "[ELF] - Linkerscript: implement EXCLUDE_FILE in the middle of a input section description."

With fix for 2 bots. Details about the fix performed is on a review page.

Initial commit message:
This is PR30387:

>From PR description:
We fail to parse

SECTIONS
{
  foo :
  {
    *(sec0 EXCLUDE_FILE (zed1.o) sec1  EXCLUDE_FILE (zed2.o) sec2 )
  }
}
The semantics according to bfd are:

Include sec1 from every file but zed1.o
Include sec2 from every file but zed2.o
Include sec0 from every file

Patch implements the support.

Differential revision: https://reviews.llvm.org/D24650

Added:
    lld/trunk/test/ELF/linkerscript/Inputs/exclude-multiple1.s
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscript/Inputs/exclude-multiple1.s
    lld/trunk/test/ELF/linkerscript/Inputs/exclude-multiple2.s
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscript/Inputs/exclude-multiple2.s
    lld/trunk/test/ELF/linkerscript/exclude-multiple.s
      - copied unchanged from r281722, lld/trunk/test/ELF/linkerscript/exclude-multiple.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=281754&r1=281753&r2=281754&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep 16 12:42:10 2016
@@ -109,10 +109,10 @@ bool LinkerScript<ELFT>::shouldKeep(Inpu
   return false;
 }
 
-static bool fileMatches(const InputSectionDescription *Desc,
-                        StringRef Filename) {
-  return const_cast<Regex &>(Desc->FileRe).match(Filename) &&
-         !const_cast<Regex &>(Desc->ExcludedFileRe).match(Filename);
+static bool fileMatches(const llvm::Regex &FileRe,
+                        const llvm::Regex &ExcludedFileRe, StringRef Filename) {
+  return const_cast<Regex &>(FileRe).match(Filename) &&
+         !const_cast<Regex &>(ExcludedFileRe).match(Filename);
 }
 
 static bool comparePriority(InputSectionData *A, InputSectionData *B) {
@@ -161,16 +161,19 @@ static bool matchConstraints(ArrayRef<In
 template <class ELFT>
 void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I,
                                               ConstraintKind Constraint) {
-  const Regex &Re = I->SectionRe;
-  for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
-    if (fileMatches(I, sys::path::filename(F->getName())))
-      for (InputSectionBase<ELFT> *S : F->getSections())
-        if (!isDiscarded(S) && !S->OutSec &&
-            const_cast<Regex &>(Re).match(S->Name))
-          I->Sections.push_back(S);
+  for (const std::pair<llvm::Regex, llvm::Regex> &V : I->SectionsVec) {
+    for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
+      if (fileMatches(I->FileRe, V.first, sys::path::filename(F->getName()))) {
+        Regex &Re = const_cast<Regex &>(V.second);
+        for (InputSectionBase<ELFT> *S : F->getSections())
+          if (!isDiscarded(S) && !S->OutSec && Re.match(S->Name))
+            I->Sections.push_back(S);
 
-  if (const_cast<Regex &>(Re).match("COMMON"))
-    I->Sections.push_back(CommonInputSection<ELFT>::X);
+        if (Re.match("COMMON"))
+          I->Sections.push_back(CommonInputSection<ELFT>::X);
+      }
+    }
+  }
 
   if (!matchConstraints<ELFT>(I->Sections, Constraint)) {
     I->Sections.clear();
@@ -698,6 +701,7 @@ private:
   std::vector<StringRef> readOutputSectionPhdrs();
   InputSectionDescription *readInputSectionDescription(StringRef Tok);
   Regex readFilePatterns();
+  void readSectionExcludes(InputSectionDescription *Cmd);
   InputSectionDescription *readInputSectionRules(StringRef FilePattern);
   unsigned readPhdrType();
   SortKind readSortKind();
@@ -991,17 +995,41 @@ SortKind ScriptParser::readSortKind() {
   return SortNone;
 }
 
+// Method reads a list of sequence of excluded files and section globs given in
+// a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+
+// Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)
+void ScriptParser::readSectionExcludes(InputSectionDescription *Cmd) {
+  llvm::Regex ExcludeFileRe;
+  std::vector<StringRef> V;
+
+  while (!Error) {
+    if (skip(")")) {
+      Cmd->SectionsVec.push_back(
+          {std::move(ExcludeFileRe), compileGlobPatterns(V)});
+      return;
+    }
+
+    if (skip("EXCLUDE_FILE")) {
+      if (!V.empty()) {
+        Cmd->SectionsVec.push_back(
+            {std::move(ExcludeFileRe), compileGlobPatterns(V)});
+        V.clear();
+      }
+
+      expect("(");
+      ExcludeFileRe = readFilePatterns();
+      continue;
+    }
+
+    V.push_back(next());
+  }
+}
+
 InputSectionDescription *
 ScriptParser::readInputSectionRules(StringRef FilePattern) {
   auto *Cmd = new InputSectionDescription(FilePattern);
   expect("(");
 
-  // Read EXCLUDE_FILE().
-  if (skip("EXCLUDE_FILE")) {
-    expect("(");
-    Cmd->ExcludedFileRe = readFilePatterns();
-  }
-
   // Read SORT().
   if (SortKind K1 = readSortKind()) {
     Cmd->SortOuter = K1;
@@ -1009,16 +1037,16 @@ ScriptParser::readInputSectionRules(Stri
     if (SortKind K2 = readSortKind()) {
       Cmd->SortInner = K2;
       expect("(");
-      Cmd->SectionRe = readFilePatterns();
+      Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()});
       expect(")");
     } else {
-      Cmd->SectionRe = readFilePatterns();
+      Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()});
     }
     expect(")");
     return Cmd;
   }
 
-  Cmd->SectionRe = readFilePatterns();
+  readSectionExcludes(Cmd);
   return Cmd;
 }
 
@@ -1031,7 +1059,8 @@ ScriptParser::readInputSectionDescriptio
     StringRef FilePattern = next();
     InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
     expect(")");
-    Opt.KeptSections.push_back(&Cmd->SectionRe);
+    for (std::pair<llvm::Regex, llvm::Regex> &Regex : Cmd->SectionsVec)
+      Opt.KeptSections.push_back(&Regex.second);
     return Cmd;
   }
   return readInputSectionRules(Tok);

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=281754&r1=281753&r2=281754&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Sep 16 12:42:10 2016
@@ -20,6 +20,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Regex.h"
 #include <functional>
+#include <list>
 
 namespace lld {
 namespace elf {
@@ -106,8 +107,8 @@ struct InputSectionDescription : BaseCom
   llvm::Regex FileRe;
   SortKind SortOuter = SortNone;
   SortKind SortInner = SortNone;
-  llvm::Regex ExcludedFileRe;
-  llvm::Regex SectionRe;
+  // Pairs of section regex and files excluded.
+  std::list<std::pair<llvm::Regex, llvm::Regex>> SectionsVec;
   std::vector<InputSectionData *> Sections;
 };
 




More information about the llvm-commits mailing list