[ELF] Remove unused synthetic sections from script commands
authorPetr Hosek <phosek@chromium.org>
Mon, 3 Jul 2017 15:49:25 +0000 (15:49 +0000)
committerPetr Hosek <phosek@chromium.org>
Mon, 3 Jul 2017 15:49:25 +0000 (15:49 +0000)
Script commands are processed before unused synthetic sections are
removed. Therefore, if a linker script matches one of these sections
it'll get emitted as an empty output section because the logic for
removing unused synthetic sections ignores script commands which
could have already matched and captured one of these sections. This
patch fixes that by also removing the unused synthetic sections from
the script commands.

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

llvm-svn: 307037

lld/ELF/Writer.cpp
lld/test/ELF/linkerscript/unused-synthetic.s [new file with mode: 0644]

index 080d8e787301348ae31c03c79ad51084a7494d14..551ca260de10433e1a034361be916100a8913039 100644 (file)
@@ -1149,8 +1149,17 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
     SS->Live = false;
     // If there are no other sections in the output section, remove it from the
     // output.
-    if (OS->Sections.empty())
+    if (OS->Sections.empty()) {
       V.erase(std::find(V.begin(), V.end(), OS));
+      // Also remove script commands matching the output section.
+      auto &Cmds = Script->Opt.Commands;
+      auto I = std::remove_if(Cmds.begin(), Cmds.end(), [&](BaseCommand *Cmd) {
+        if (auto *OSCmd = dyn_cast<OutputSectionCommand>(Cmd))
+          return OSCmd->Sec == OS;
+        return false;
+      });
+      Cmds.erase(I, Cmds.end());
+    }
   }
 }
 
diff --git a/lld/test/ELF/linkerscript/unused-synthetic.s b/lld/test/ELF/linkerscript/unused-synthetic.s
new file mode 100644 (file)
index 0000000..c9295ff
--- /dev/null
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN:    .got  : { *(.got) } \
+# RUN:    .plt  : { *(.plt) } \
+# RUN:    .text : { *(.text) } \
+# RUN:  }" > %t.script
+# RUN: ld.lld -shared -o %t.so --script %t.script %t.o
+
+# RUN: llvm-objdump -section-headers %t.so | FileCheck %s
+# CHECK-NOT:  .got
+# CHECK-NOT:  .plt
+# CHECK:      .text
+# CHECK-NEXT: .dynsym
+
+.global _start
+_start:
+  nop