diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-11-09 17:44:10 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-11-09 17:44:10 +0000 |
| commit | 8ea46e00f1ec1f5ebf3fdabaff3759ac542d2ca8 (patch) | |
| tree | a6018979d8542917d3f69d5fdc18d7465399e061 | |
| parent | 3656e3064b54f00ee884fc36120bcb25673233af (diff) | |
| download | bcm5719-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.cpp | 15 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 2 | ||||
| -rw-r--r-- | lld/test/elf2/gc-sections-eh.s | 19 |
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 |

