[PATCH] D42681: [ELF] - Remove unused synthetic sections correctly.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 30 02:53:14 PST 2018


grimar created this revision.
grimar added reviewers: ruiu, espindola.
Herald added a subscriber: emaste.
grimar retitled this revision from "[ELF] - Remove unsued synthetic sections correctly." to "[ELF] - Remove unused synthetic sections correctly.".

This is PR35740 which now crashes
because we remove unused synthetic sections incorrectly.

We can keep input section description and corresponding output
section live even if it must be empty and dead. 
This results in a crash because SHF_LINK_ORDER handling code
tries to access first section which is nullptr in this case.

It is based on https://reviews.llvm.org/D37520 which tried to fix the same issue.


https://reviews.llvm.org/D42681

Files:
  ELF/Writer.cpp
  test/ELF/linkerscript/unused-synthetic.s
  test/ELF/linkerscript/unused-synthetic2.s


Index: test/ELF/linkerscript/unused-synthetic2.s
===================================================================
--- test/ELF/linkerscript/unused-synthetic2.s
+++ test/ELF/linkerscript/unused-synthetic2.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=armv7-unknown-linux-gnueabi %s -o %t.o
+# RUN: echo "SECTIONS { .trap : { *(.ARM.exidx) *(.dummy) } }" > %t.script
+
+## We incorrectly removed unused synthetic sections and crashed before.
+## Check we do not crash and do not produce .trap output section.
+# RUN: ld.lld -shared -o %t.so --script %t.script %t.o
+# RUN: llvm-objdump -section-headers %t.so | FileCheck %s
+# CHECK-NOT: .trap
Index: test/ELF/linkerscript/unused-synthetic.s
===================================================================
--- test/ELF/linkerscript/unused-synthetic.s
+++ test/ELF/linkerscript/unused-synthetic.s
@@ -1,7 +1,7 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: echo "SECTIONS { \
-# RUN:    .got  : { *(.got) } \
+# RUN:    .got  : { *(.got) *(.got) } \
 # RUN:    .plt  : { *(.plt) } \
 # RUN:    .text : { *(.text) } \
 # RUN:  }" > %t.script
Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -1314,23 +1314,26 @@
     if (!OS || !SS->empty())
       continue;
 
-    std::vector<BaseCommand *>::iterator Empty = OS->SectionCommands.end();
-    for (auto I = OS->SectionCommands.begin(), E = OS->SectionCommands.end();
-         I != E; ++I) {
-      BaseCommand *B = *I;
+    // If we reach here, then SS is an unused synthetic section and we want to
+    // remove it from corresponding input section description of output section.
+    for (BaseCommand *B : OS->SectionCommands) {
       if (auto *ISD = dyn_cast<InputSectionDescription>(B)) {
-        llvm::erase_if(ISD->Sections,
-                       [=](InputSection *IS) { return IS == SS; });
-        if (ISD->Sections.empty())
-          Empty = I;
+        auto It = llvm::find(ISD->Sections, SS);
+        if (It == ISD->Sections.end())
+          continue;
+        ISD->Sections.erase(It);
+        break;
       }
     }
-    if (Empty != OS->SectionCommands.end())
-      OS->SectionCommands.erase(Empty);
 
-    // If there are no other sections in the output section, remove it from the
-    // output.
-    if (OS->SectionCommands.empty())
+    // If there are no other alive sections or commands left in the output
+    // section description, we remove it from the output.
+    bool IsEmpty = llvm::all_of(OS->SectionCommands, [](BaseCommand *B) {
+      if (auto *ISD = dyn_cast<InputSectionDescription>(B))
+        return ISD->Sections.empty();
+      return false;
+    });
+    if (IsEmpty)
       OS->Live = false;
   }
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42681.131937.patch
Type: text/x-patch
Size: 2815 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180130/aa917a1b/attachment.bin>


More information about the llvm-commits mailing list