summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-11-09 17:44:10 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-11-09 17:44:10 +0000
commit8ea46e00f1ec1f5ebf3fdabaff3759ac542d2ca8 (patch)
treea6018979d8542917d3f69d5fdc18d7465399e061
parent3656e3064b54f00ee884fc36120bcb25673233af (diff)
downloadbcm5719-llvm-8ea46e00f1ec1f5ebf3fdabaff3759ac542d2ca8.tar.gz
bcm5719-llvm-8ea46e00f1ec1f5ebf3fdabaff3759ac542d2ca8.zip
Start treating .eh_frame specially.
For now, just don't follow edges leaving from it to mark other sections live. llvm-svn: 252493
-rw-r--r--lld/ELF/MarkLive.cpp15
-rw-r--r--lld/ELF/OutputSections.cpp2
-rw-r--r--lld/test/elf2/gc-sections-eh.s19
3 files changed, 31 insertions, 5 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 7e73a1fd78e..cc94a662f4e 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -71,7 +71,7 @@ template <class ELFT> static bool isReserved(InputSectionBase<ELFT> *Sec) {
default:
StringRef S = Sec->getSectionName();
return S.startswith(".init") || S.startswith(".fini") ||
- S.startswith(".jcr") || S == ".eh_frame";
+ S.startswith(".jcr");
}
}
@@ -109,11 +109,18 @@ template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) {
}
// Preserve special sections.
- for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles())
- for (InputSectionBase<ELFT> *Sec : F->getSections())
- if (Sec && Sec != &InputSection<ELFT>::Discarded)
+ for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles()) {
+ for (InputSectionBase<ELFT> *Sec : F->getSections()) {
+ if (Sec && Sec != &InputSection<ELFT>::Discarded) {
if (isReserved(Sec))
Enqueue(Sec);
+ else if (Sec->getSectionName() == ".eh_frame")
+ // .eh_frame is special. It should be marked live so that we don't
+ // drop it, but it should not keep any section alive.
+ Sec->Live = true;
+ }
+ }
+ }
// Mark all reachable sections.
while (!Q.empty())
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index cfd6133cfee..0a6c33c1d02 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -707,7 +707,7 @@ lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
// and must be treated specially. For now we just replace the symbol with
// 0.
InputSectionBase<ELFT> *Section = File.getSection(*Sym);
- if (Section == &InputSection<ELFT>::Discarded)
+ if (Section == &InputSection<ELFT>::Discarded || !Section->isLive())
return Addend;
uintX_t VA = Section->OutSec->getVA();
diff --git a/lld/test/elf2/gc-sections-eh.s b/lld/test/elf2/gc-sections-eh.s
new file mode 100644
index 00000000000..71a1c3a1712
--- /dev/null
+++ b/lld/test/elf2/gc-sections-eh.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld2 %t -o %t2 --gc-sections
+# RUN: llvm-readobj -t %t2 | FileCheck %s
+
+# CHECK-NOT: foo
+
+ .section .text,"ax",@progbits,unique,0
+ .globl foo
+foo:
+ .cfi_startproc
+ .cfi_endproc
+
+ .section .text,"ax",@progbits,unique,1
+ .globl _start
+_start:
+ .cfi_startproc
+ .cfi_endproc
OpenPOWER on IntegriCloud