diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -618,6 +618,22 @@ // For each secion group, connect its members in a circular doubly-linked list // via nextInSectionGroup. See the comment in markLive(). for (ArrayRef entries : selectedGroups) { + bool hasAlloc = false; + for (uint32_t secIndex : entries.slice(1)) { + if (secIndex >= this->sections.size()) + continue; + InputSectionBase *s = this->sections[secIndex]; + if (!s || s == &InputSection::discarded) + continue; + if (s->flags & SHF_ALLOC) + hasAlloc = true; + } + + // If no member has the SHF_ALLOC flag, retain the whole group. This rule + // retains .debug_types and .rela.debug_types. + if (!hasAlloc) + continue; + InputSectionBase *head; InputSectionBase *prev = nullptr; for (uint32_t secIndex : entries.slice(1)) { diff --git a/lld/test/ELF/gc-sections-group-debug.s b/lld/test/ELF/gc-sections-group-debug.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/gc-sections-group-debug.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +## Check that group members are retained, if no member has the SHF_ALLOC flag. +## This rule retains .debug_types and .rela.debug_types emitted by clang/gcc. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --gc-sections %t.o -o %t +# RUN: llvm-readobj -S %t | FileCheck %s + +# CHECK: Name: .debug_types + +.section .debug_types,"G",@progbits,abcd,comdat +.quad .debug_types diff --git a/lld/test/ELF/gc-sections-group.s b/lld/test/ELF/gc-sections-group.s --- a/lld/test/ELF/gc-sections-group.s +++ b/lld/test/ELF/gc-sections-group.s @@ -1,7 +1,7 @@ # REQUIRES: x86 ## Check that group members are retained or discarded as a unit, and -## non-SHF_ALLOC sections in a group are subject to garbage collection. -## This is compatible with GNU ld. +## non-SHF_ALLOC sections in a group are subject to garbage collection, +## if at least one member has the SHF_ALLOC flag. # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o # RUN: ld.lld --gc-sections %t.o -o %t.dead