Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -10,14 +10,31 @@ #ifndef LLD_ELF_WRITER_H #define LLD_ELF_WRITER_H +#include + +namespace llvm { + class StringRef; +} + namespace lld { namespace elf { template class SymbolTable; +template class InputSectionBase; +template class ObjectFile; template void writeResult(SymbolTable *Symtab); template void markLive(); + +template +llvm::StringRef getOutputSectionName(InputSectionBase *S); + +template +void reportDiscarded(InputSectionBase *IS, + const std::unique_ptr> &File); + +template bool isDiscarded(InputSectionBase *S); } } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -81,8 +81,6 @@ void writeHeader(); void writeSections(); void writeBuildId(); - bool isDiscarded(InputSectionBase *IS) const; - StringRef getOutputSectionName(InputSectionBase *S) const; bool needsInterpSection() const { return !Symtab.getSharedFiles().empty() && !Config->DynamicLinker.empty(); } @@ -119,6 +117,35 @@ }; } // anonymous namespace +template +StringRef elf::getOutputSectionName(InputSectionBase *S) { + StringRef Dest = Script::X->getOutputSection(S); + if (!Dest.empty()) + return Dest; + + StringRef Name = S->getSectionName(); + for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", + ".init_array.", ".fini_array.", ".ctors.", ".dtors.", + ".tbss.", ".gcc_except_table.", ".tdata."}) + if (Name.startswith(V)) + return V.drop_back(); + return Name; +} + +template +void elf::reportDiscarded(InputSectionBase *IS, + const std::unique_ptr> &File) { + if (!Config->PrintGcSections || !IS || IS->Live) + return; + llvm::errs() << "removing unused section from '" << IS->getSectionName() + << "' in file '" << File->getName() << "'\n"; +} + +template bool elf::isDiscarded(InputSectionBase *S) { + return !S || S == &InputSection::Discarded || !S->Live || + Script::X->isDiscarded(S); +} + template void elf::writeResult(SymbolTable *Symtab) { typedef typename ELFT::uint uintX_t; typedef typename ELFT::Ehdr Elf_Ehdr; @@ -1071,36 +1098,6 @@ } template -StringRef Writer::getOutputSectionName(InputSectionBase *S) const { - StringRef Dest = Script::X->getOutputSection(S); - if (!Dest.empty()) - return Dest; - - StringRef Name = S->getSectionName(); - for (StringRef V : {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.", - ".init_array.", ".fini_array.", ".ctors.", ".dtors.", - ".tbss.", ".gcc_except_table.", ".tdata."}) - if (Name.startswith(V)) - return V.drop_back(); - return Name; -} - -template -void reportDiscarded(InputSectionBase *IS, - const std::unique_ptr> &File) { - if (!Config->PrintGcSections || !IS || IS->Live) - return; - llvm::errs() << "removing unused section from '" << IS->getSectionName() - << "' in file '" << File->getName() << "'\n"; -} - -template -bool Writer::isDiscarded(InputSectionBase *S) const { - return !S || S == &InputSection::Discarded || !S->Live || - Script::X->isDiscarded(S); -} - -template static Symbol *addOptionalSynthetic(SymbolTable &Table, StringRef Name, OutputSectionBase *Sec, typename ELFT::uint Val) {