diff options
| author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-09-26 09:04:16 +0000 |
|---|---|---|
| committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-09-26 09:04:16 +0000 |
| commit | 527a84ec120fa0c752e3a80e26e97bb835d15070 (patch) | |
| tree | 394e2fb8f20c6ec8e9a0dc5838c2426281ec61cd | |
| parent | 8287b1bce1e9ca3e0d396b941019885237114bb0 (diff) | |
| download | bcm5719-llvm-527a84ec120fa0c752e3a80e26e97bb835d15070.tar.gz bcm5719-llvm-527a84ec120fa0c752e3a80e26e97bb835d15070.zip | |
Linkerscript: don't crash when GC .debug_line
Differential revision: https://reviews.llvm.org/D24870
llvm-svn: 282393
| -rw-r--r-- | lld/ELF/MarkLive.cpp | 13 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/Inputs/comdat-gc.s | 5 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/comdat-gc.s | 14 |
3 files changed, 24 insertions, 8 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 10d4f3d13d3..5d0f5a0d87a 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -81,13 +81,6 @@ static ResolvedReloc<ELFT> resolveReloc(InputSectionBase<ELFT> &Sec, template <class ELFT> static void forEachSuccessor(InputSection<ELFT> &Sec, std::function<void(ResolvedReloc<ELFT>)> Fn) { - // Skip over discarded sections. This in theory shouldn't happen, because - // the ELF spec doesn't allow a relocation to point to a deduplicated - // COMDAT section directly. Unfortunately this happens in practice (e.g. - // .eh_frame) so we need to add a check. - if (&Sec == &InputSection<ELFT>::Discarded) - return; - ELFFile<ELFT> &Obj = Sec.getFile()->getObj(); for (const typename ELFT::Shdr *RelSec : Sec.RelocSections) { if (RelSec->sh_type == SHT_RELA) { @@ -198,7 +191,11 @@ template <class ELFT> void elf::markLive() { SmallVector<InputSection<ELFT> *, 256> Q; auto Enqueue = [&](ResolvedReloc<ELFT> R) { - if (!R.Sec) + // Skip over discarded sections. This in theory shouldn't happen, because + // the ELF spec doesn't allow a relocation to point to a deduplicated + // COMDAT section directly. Unfortunately this happens in practice (e.g. + // .eh_frame) so we need to add a check. + if (!R.Sec || R.Sec == &InputSection<ELFT>::Discarded) return; // Usually, a whole section is marked as live or dead, but in mergeable diff --git a/lld/test/ELF/linkerscript/Inputs/comdat-gc.s b/lld/test/ELF/linkerscript/Inputs/comdat-gc.s new file mode 100644 index 00000000000..da29d5b3830 --- /dev/null +++ b/lld/test/ELF/linkerscript/Inputs/comdat-gc.s @@ -0,0 +1,5 @@ +.file 1 "test/ELF/linkerscript/Inputs/comdat_gc.s" + +.section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat +.loc 1 5 + ret diff --git a/lld/test/ELF/linkerscript/comdat-gc.s b/lld/test/ELF/linkerscript/comdat-gc.s new file mode 100644 index 00000000000..63dcf85c5a6 --- /dev/null +++ b/lld/test/ELF/linkerscript/comdat-gc.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/comdat-gc.s -o %t1 +# RUN: echo "SECTIONS { .text : { *(.text*) } }" > %t.script +# RUN: ld.lld --gc-sections --script %t.script %t %t1 -o %t2 +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC1 %s + +# GC1: Name: .debug_line + +.file 1 "test/ELF/linkerscript/comdat_gc.s" +.section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat +.loc 1 14 + ret |

