summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-02-07 09:11:07 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-02-07 09:11:07 +0000
commit3d5e86e5ee8cbf39939f533dce4c002e8dbf139a (patch)
tree045b269e76574e47d89f702a549fd0555e71481f
parent69246ca7879d81dc3f07d52f768f7550519fbcb6 (diff)
downloadbcm5719-llvm-3d5e86e5ee8cbf39939f533dce4c002e8dbf139a.tar.gz
bcm5719-llvm-3d5e86e5ee8cbf39939f533dce4c002e8dbf139a.zip
[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. Patch fixes the issue. Differential revision: https://reviews.llvm.org/D42681 llvm-svn: 324463
-rw-r--r--lld/ELF/Writer.cpp26
-rw-r--r--lld/test/ELF/linkerscript/unused-synthetic.s2
-rw-r--r--lld/test/ELF/linkerscript/unused-synthetic2.s9
3 files changed, 22 insertions, 15 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index eddf1741436..9de734a1c0d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1346,23 +1346,21 @@ static void removeUnusedSyntheticSections() {
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 (auto *ISD = dyn_cast<InputSectionDescription>(B)) {
+ // 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;
- }
- }
- 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;
}
}
diff --git a/lld/test/ELF/linkerscript/unused-synthetic.s b/lld/test/ELF/linkerscript/unused-synthetic.s
index b7cedbc8e09..fb334213aa6 100644
--- a/lld/test/ELF/linkerscript/unused-synthetic.s
+++ b/lld/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
diff --git a/lld/test/ELF/linkerscript/unused-synthetic2.s b/lld/test/ELF/linkerscript/unused-synthetic2.s
new file mode 100644
index 00000000000..37ebc50b344
--- /dev/null
+++ b/lld/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
OpenPOWER on IntegriCloud