diff options
-rw-r--r-- | lld/ELF/MarkLive.cpp | 7 | ||||
-rw-r--r-- | lld/test/ELF/comdat.s | 9 |
2 files changed, 16 insertions, 0 deletions
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index 496537748c7..6628973b024 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -81,6 +81,13 @@ 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) { diff --git a/lld/test/ELF/comdat.s b/lld/test/ELF/comdat.s index d422ee8fba3..5b190b177ee 100644 --- a/lld/test/ELF/comdat.s +++ b/lld/test/ELF/comdat.s @@ -5,6 +5,15 @@ // RUN: llvm-readobj -s -t %t | FileCheck --check-prefix=READ %s // REQUIRES: x86 +// Check that we don't crash with --gc-section and that we print a list of +// reclaimed sections on stderr. +// RUN: ld.lld --gc-sections --print-gc-sections -shared %t.o %t.o %t2.o -o %t \ +// RUN: 2>&1 | FileCheck --check-prefix=GC %s +// GC: removing unused section from '.text' in file +// GC: removing unused section from '.text3' in file +// GC: removing unused section from '.text' in file +// GC: removing unused section from '.text' in file + .section .text2,"axG",@progbits,foo,comdat,unique,0 foo: nop |