[lld] r276825 - [ELF/LinkerScript] Support EXCLUDE_FILE inside KEEP.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 26 18:44:01 PDT 2016


Author: davide
Date: Tue Jul 26 20:44:01 2016
New Revision: 276825

URL: http://llvm.org/viewvc/llvm-project?rev=276825&view=rev
Log:
[ELF/LinkerScript] Support EXCLUDE_FILE inside KEEP.

Differential Revision:	https://reviews.llvm.org/D22795

Added:
    lld/trunk/test/ELF/linkerscript/Inputs/include.s
    lld/trunk/test/ELF/linkerscript/Inputs/notinclude.s
    lld/trunk/test/ELF/linkerscript/linkerscript-excludefile.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=276825&r1=276824&r2=276825&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Jul 26 20:44:01 2016
@@ -79,15 +79,15 @@ static bool match(ArrayRef<StringRef> Pa
 // input sections start with ".foo." or ".bar." should be added to
 // ".text" section.
 template <class ELFT>
-std::vector<std::pair<StringRef, ArrayRef<StringRef>>>
+std::vector<std::pair<StringRef, const InputSectionDescription *>>
 LinkerScript<ELFT>::getSectionMap() {
-  std::vector<std::pair<StringRef, ArrayRef<StringRef>>> Ret;
+  std::vector<std::pair<StringRef, const InputSectionDescription *>> Ret;
 
   for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands)
     if (auto *Cmd1 = dyn_cast<OutputSectionCommand>(Base1.get()))
       for (const std::unique_ptr<BaseCommand> &Base2 : Cmd1->Commands)
         if (auto *Cmd2 = dyn_cast<InputSectionDescription>(Base2.get()))
-          Ret.emplace_back(Cmd1->Name, Cmd2->Patterns);
+          Ret.emplace_back(Cmd1->Name, Cmd2);
 
   return Ret;
 }
@@ -95,13 +95,17 @@ LinkerScript<ELFT>::getSectionMap() {
 // Returns input sections filtered by given glob patterns.
 template <class ELFT>
 std::vector<InputSectionBase<ELFT> *>
-LinkerScript<ELFT>::getInputSections(ArrayRef<StringRef> Patterns) {
+LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
+  ArrayRef<StringRef> Patterns = I->Patterns;
+  ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles;
   std::vector<InputSectionBase<ELFT> *> Ret;
   for (const std::unique_ptr<ObjectFile<ELFT>> &F :
        Symtab<ELFT>::X->getObjectFiles())
     for (InputSectionBase<ELFT> *S : F->getSections())
       if (!isDiscarded(S) && !S->OutSec && match(Patterns, S->getSectionName()))
-        Ret.push_back(S);
+        if (ExcludedFiles.empty() ||
+            !match(ExcludedFiles, sys::path::filename(F->getName())))
+          Ret.push_back(S);
   return Ret;
 }
 
@@ -123,8 +127,8 @@ LinkerScript<ELFT>::createSections(Outpu
 
   for (auto &P : getSectionMap()) {
     StringRef OutputName = P.first;
-    ArrayRef<StringRef> InputPatterns = P.second;
-    for (InputSectionBase<ELFT> *S : getInputSections(InputPatterns)) {
+    const InputSectionDescription *I = P.second;
+    for (InputSectionBase<ELFT> *S : getInputSections(I)) {
       if (OutputName == "/DISCARD/") {
         S->Live = false;
         reportDiscarded(S);
@@ -420,6 +424,7 @@ private:
   void readAsNeeded();
   void readEntry();
   void readExtern();
+  std::unique_ptr<InputSectionDescription> readFilePattern();
   void readGroup();
   void readKeep(OutputSectionCommand *Cmd);
   void readInclude();
@@ -662,16 +667,31 @@ static int precedence(StringRef Op) {
       .Default(-1);
 }
 
-void ScriptParser::readKeep(OutputSectionCommand *Cmd) {
-  expect("(");
+std::unique_ptr<InputSectionDescription> ScriptParser::readFilePattern() {
   expect("*");
   expect("(");
-  auto *InCmd = new InputSectionDescription();
-  Cmd->Commands.emplace_back(InCmd);
-  while (!Error && !skip(")")) {
-    Opt.KeptSections.push_back(peek());
+
+  auto InCmd = llvm::make_unique<InputSectionDescription>();
+
+  if (skip("EXCLUDE_FILE")) {
+    expect("(");
+    while (!Error && !skip(")"))
+      InCmd->ExcludedFiles.push_back(next());
     InCmd->Patterns.push_back(next());
+    expect(")");
+  } else {
+    while (!Error && !skip(")"))
+      InCmd->Patterns.push_back(next());
   }
+  return InCmd;
+}
+
+void ScriptParser::readKeep(OutputSectionCommand *Cmd) {
+  expect("(");
+  std::unique_ptr<InputSectionDescription> InCmd = readFilePattern();
+  Opt.KeptSections.insert(Opt.KeptSections.end(), InCmd->Patterns.begin(),
+                          InCmd->Patterns.end());
+  Cmd->Commands.push_back(std::move(InCmd));
   expect(")");
 }
 

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=276825&r1=276824&r2=276825&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Tue Jul 26 20:44:01 2016
@@ -83,6 +83,7 @@ struct OutputSectionCommand : BaseComman
 struct InputSectionDescription : BaseCommand {
   InputSectionDescription() : BaseCommand(InputSectionKind) {}
   static bool classof(const BaseCommand *C);
+  std::vector<StringRef> ExcludedFiles;
   std::vector<StringRef> Patterns;
 };
 
@@ -132,10 +133,11 @@ public:
   bool hasPhdrsCommands();
 
 private:
-  std::vector<std::pair<StringRef, ArrayRef<StringRef>>> getSectionMap();
+  std::vector<std::pair<StringRef, const InputSectionDescription *>>
+  getSectionMap();
 
   std::vector<InputSectionBase<ELFT> *>
-  getInputSections(ArrayRef<StringRef> Patterns);
+  getInputSections(const InputSectionDescription *);
 
   // "ScriptConfig" is a bit too long, so define a short name for it.
   ScriptConfiguration &Opt = *ScriptConfig;

Added: lld/trunk/test/ELF/linkerscript/Inputs/include.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/Inputs/include.s?rev=276825&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/Inputs/include.s (added)
+++ lld/trunk/test/ELF/linkerscript/Inputs/include.s Tue Jul 26 20:44:01 2016
@@ -0,0 +1,5 @@
+.section .text
+.globl _potato
+_potato:
+  nop
+  nop

Added: lld/trunk/test/ELF/linkerscript/Inputs/notinclude.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/Inputs/notinclude.s?rev=276825&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/Inputs/notinclude.s (added)
+++ lld/trunk/test/ELF/linkerscript/Inputs/notinclude.s Tue Jul 26 20:44:01 2016
@@ -0,0 +1,4 @@
+.section .text
+.globl tomato
+tomato:
+  movl $1, %eax

Added: lld/trunk/test/ELF/linkerscript/linkerscript-excludefile.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript-excludefile.s?rev=276825&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript-excludefile.s (added)
+++ lld/trunk/test/ELF/linkerscript/linkerscript-excludefile.s Tue Jul 26 20:44:01 2016
@@ -0,0 +1,48 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN:   %p/Inputs/include.s -o %t2
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN:   %p/Inputs/notinclude.s -o %t3.notinclude
+
+# RUN: echo "SECTIONS {} " > %t.script
+# RUN: ld.lld -o %t --script %t.script %t1 %t2 %t3.notinclude
+# RUN: llvm-objdump -d %t | \
+# RUN:   FileCheck %s
+
+# CHECK: Disassembly of section .text:
+# CHECK: _start:
+# CHECK:      120:       48 c7 c0 3c 00 00 00    movq    $60, %rax
+# CHECK:      127:       48 c7 c7 2a 00 00 00    movq    $42, %rdi
+# CHECK:      12e:       00 00   addb    %al, (%rax)
+# CHECK: _potato:
+# CHECK:      130:       90      nop
+# CHECK:      131:       90      nop
+# CHECK:      132:       00 00   addb    %al, (%rax)
+# CHECK: tomato:
+# CHECK:      134:       b8 01 00 00 00  movl    $1, %eax
+
+# RUN: echo "SECTIONS { .patatino : \
+# RUN: { KEEP(*(EXCLUDE_FILE(*notinclude) .text)) } }" \
+# RUN:  > %t.script
+# RUN: ld.lld -o %t2 --script %t.script %t1 %t2 %t3.notinclude
+# RUN: llvm-objdump -d %t2 | \
+# RUN:   FileCheck %s --check-prefix=EXCLUDE
+
+# EXCLUDE: Disassembly of section .patatino:
+# EXCLUDE: _start:
+# EXCLUDE:      120:       48 c7 c0 3c 00 00 00    movq    $60, %rax
+# EXCLUDE:      127:       48 c7 c7 2a 00 00 00    movq    $42, %rdi
+# EXCLUDE:      12e:       00 00   addb    %al, (%rax)
+# EXCLUDE: _potato:
+# EXCLUDE:      130:       90      nop
+# EXCLUDE:      131:       90      nop
+# EXCLUDE: Disassembly of section .text:
+# EXCLUDE: tomato:
+# EXCLUDE:      134:       b8 01 00 00 00  movl    $1, %eax
+
+.section .text
+.globl _start
+_start:
+    mov $60, %rax
+    mov $42, %rdi




More information about the llvm-commits mailing list