Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -276,7 +276,8 @@ void LinkerScript::discard(ArrayRef *> V) { for (InputSectionBase *S : V) { S->Live = false; - reportDiscarded(S); + if (S == In::ShStrTab) + error("discarding .shstrtab section is not allowed"); InputSection *IS = dyn_cast>(S); if (!IS || IS->DependentSections.empty()) Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -575,6 +575,13 @@ Type == SHT_NOTE; } +template static void reportDiscarded(InputSectionBase *IS) { + if (!Config->PrintGcSections) + return; + errs() << "removing unused section from '" << IS->Name << "' in file '" + << IS->getFile()->getName() << "'\n"; +} + template void OutputSectionFactory::addInputSec(InputSectionBase *IS, StringRef OutsecName) { Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -52,7 +52,6 @@ template bool allocateHeaders(std::vector &, llvm::ArrayRef, uint64_t Min); -template void reportDiscarded(InputSectionBase *IS); template uint32_t getMipsEFlags(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -119,15 +119,6 @@ return Name; } -template void elf::reportDiscarded(InputSectionBase *IS) { - if (IS == In::ShStrTab) - error("discarding .shstrtab section is not allowed"); - if (!Config->PrintGcSections) - return; - errs() << "removing unused section from '" << IS->Name << "' in file '" - << IS->getFile()->getName() << "'\n"; -} - template static bool needsInterpSection() { return !Symtab::X->getSharedFiles().empty() && !Config->DynamicLinker.empty() && @@ -1855,8 +1846,3 @@ template bool elf::isRelroSection(const OutputSectionBase *); template bool elf::isRelroSection(const OutputSectionBase *); template bool elf::isRelroSection(const OutputSectionBase *); - -template void elf::reportDiscarded(InputSectionBase *); -template void elf::reportDiscarded(InputSectionBase *); -template void elf::reportDiscarded(InputSectionBase *); -template void elf::reportDiscarded(InputSectionBase *); Index: test/ELF/linkerscript/discard-print-gc.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/discard-print-gc.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: echo "SECTIONS { /DISCARD/ : { *(.foo) } }" > %t.script +# RUN: llvm-mc -triple x86_64-pc-linux %s -o %t.o -filetype=obj +# RUN: ld.lld -o %t.so --gc-sections %t.o --print-gc-sections -shared 2>&1 | \ +# RUN: FileCheck -check-prefix=CHECK %s +# RUN: ld.lld -o %t.so -T %t.script %t.o --print-gc-sections -shared 2>&1 | \ +# RUN: FileCheck -check-prefix=QUIET --allow-empty %s + +.section .foo,"a" +.quad 0 + +# CHECK: removing unused section from '.foo' +# QUIET-NOT: removing unused section from '.foo'