Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -75,6 +75,22 @@ return check(File->getObj().getSectionContents(Hdr)); } +// Return true if a section with given section flags is live (will never be +// GCed) by default. If a section can be GCed, this function returns false. +static bool isLiveByDefault(uint64_t Flags, uint32_t Type) { + // If GC is enabled, all memory-mapped sections are subject of GC. + if (!Config->GcSections) + return true; + if (Flags & SHF_ALLOC) + return false; + + // Besides that, relocation sections can also be GCed because their + // relocation target sections may be GCed. This doesn't really matter + // in most cases because the linker usually consumes relocation + // sections instead of emitting them, but -emit-reloc needs this. + return Type != SHT_REL && Type != SHT_RELA; +} + InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type, uint64_t Entsize, uint32_t Link, uint32_t Info, @@ -83,7 +99,7 @@ : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info, Link), File(File), Data(Data), Repl(this) { - Live = !Config->GcSections || !(Flags & SHF_ALLOC); + Live = isLiveByDefault(Flags, Type); Assigned = false; NumRelocations = 0; AreRelocsRela = false; Index: test/ELF/emit-relocs-gc.s =================================================================== --- test/ELF/emit-relocs-gc.s +++ test/ELF/emit-relocs-gc.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## Show that we emit .rela.bar when GC is disabled. +# RUN: ld.lld --emit-relocs %t.o -o %t +# RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=NOGC +# NOGC: .rela.bar + +## GC collects .bar section and we exclude .rela.bar from output. +# RUN: ld.lld --gc-sections --emit-relocs --print-gc-sections %t.o -o %t \ +# RUN: | FileCheck --check-prefix=MSG %s +# MSG: removing unused section from '.bar' in file +# MSG: removing unused section from '.rela.bar' in file +# RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=GC +# GC-NOT: rela.bar + +.section .bar,"a" +.quad .bar