From b6e4aae2cc269bbdce9263cd49dcd582840b333a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 21 Oct 2020 10:11:20 -0700 Subject: [PATCH] [ELF] --gc-sections: retain dependent sections of non-SHF_ALLOC sections Fix http://lists.llvm.org/pipermail/llvm-dev/2020-October/145908.html Currently non-SHF_ALLOC SHT_REL[A] (due to --emit-relocs) and SHF_LINK_ORDER are not marked live. Reviewed By: grimar, psmith Differential Revision: https://reviews.llvm.org/D89841 --- lld/ELF/MarkLive.cpp | 21 ++++++++++++--------- lld/test/ELF/gc-sections-linkorder2.s | 6 ++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index af6c08c..fe5d32c 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -339,16 +339,16 @@ template void elf::markLive() { // Otherwise, do mark-sweep GC. // - // The -gc-sections option works only for SHF_ALLOC sections - // (sections that are memory-mapped at runtime). So we can - // unconditionally make non-SHF_ALLOC sections alive except - // SHF_LINK_ORDER and SHT_REL/SHT_RELA sections. + // The -gc-sections option works only for SHF_ALLOC sections (sections that + // are memory-mapped at runtime). So we can unconditionally make non-SHF_ALLOC + // sections alive except SHF_LINK_ORDER, SHT_REL/SHT_RELA sections, and + // sections in a group. // // Usually, non-SHF_ALLOC sections are not removed even if they are - // unreachable through relocations because reachability is not - // a good signal whether they are garbage or not (e.g. there is - // usually no section referring to a .comment section, but we - // want to keep it.). + // unreachable through relocations because reachability is not a good signal + // whether they are garbage or not (e.g. there is usually no section referring + // to a .comment section, but we want to keep it.) When a non-SHF_ALLOC + // section is retained, we also retain sections dependent on it. // // Note on SHF_LINK_ORDER: Such sections contain metadata and they // have a reverse dependency on the InputSection they are linked with. @@ -370,8 +370,11 @@ template void elf::markLive() { bool isLinkOrder = (sec->flags & SHF_LINK_ORDER); bool isRel = (sec->type == SHT_REL || sec->type == SHT_RELA); - if (!isAlloc && !isLinkOrder && !isRel && !sec->nextInSectionGroup) + if (!isAlloc && !isLinkOrder && !isRel && !sec->nextInSectionGroup) { sec->markLive(); + for (InputSection *isec : sec->dependentSections) + isec->markLive(); + } } // Follow the graph to mark all live sections. diff --git a/lld/test/ELF/gc-sections-linkorder2.s b/lld/test/ELF/gc-sections-linkorder2.s index b22bc58..2024972 100644 --- a/lld/test/ELF/gc-sections-linkorder2.s +++ b/lld/test/ELF/gc-sections-linkorder2.s @@ -14,3 +14,9 @@ _start: .quad 0 .section .zed,"ao",@progbits,.foo .quad 0 + +.section .nonalloc +.quad 0 + +.section .nonalloc_linkorder,"o",@progbits,.nonalloc +.quad 0 -- 2.7.4