Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -661,6 +661,35 @@ static OutputSectionBase *ProgramHeaders; }; +template struct SectionKey { + typedef typename std::conditional::type uintX_t; + StringRef Name; + uint32_t Type; + uintX_t Flags; + uintX_t Alignment; +}; + +// This class knows how to create an output section for a given +// input section. Output section type is determined by various +// factors, including input section's sh_flags, sh_type and +// linker scripts. +template class OutputSectionFactory { + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::uint uintX_t; + typedef typename SectionKey Key; + +public: + std::pair *, bool> create(InputSectionBase *C, + StringRef OutsecName); + + OutputSectionBase *lookup(StringRef Name, uint32_t Type, uintX_t Flags); + +private: + Key createKey(InputSectionBase *C, StringRef OutsecName); + + llvm::SmallDenseMap *> Map; +}; + template BuildIdSection *Out::BuildId; template DynamicSection *Out::Dynamic; template EhFrameHeader *Out::EhFrameHdr; @@ -692,4 +721,15 @@ } // namespace elf } // namespace lld -#endif // LLD_ELF_OUTPUT_SECTIONS_H +namespace llvm { +template struct DenseMapInfo> { + typedef typename lld::elf::SectionKey Key; + + static Key getEmptyKey(); + static Key getTombstoneKey(); + static unsigned getHashValue(const Key &Val); + static bool isEqual(const Key &LHS, const Key &RHS); +}; +} + +#endif // LLD_ELF_OUTPUT_SECTIONS_Hlld::elf::SectionKey Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -1751,6 +1751,89 @@ S->OutSec = this; } +template +std::pair *, bool> +OutputSectionFactory::create(InputSectionBase *C, + StringRef OutsecName) { + SectionKey Key = createKey(C, OutsecName); + OutputSectionBase *&Sec = Map[Key]; + if (Sec) + return {Sec, false}; + + switch (C->SectionKind) { + case InputSectionBase::Regular: + Sec = new OutputSection(Key.Name, Key.Type, Key.Flags); + break; + case InputSectionBase::EHFrame: + return {Out::EhFrame, false}; + case InputSectionBase::Merge: + Sec = new MergeOutputSection(Key.Name, Key.Type, Key.Flags, + Key.Alignment); + break; + case InputSectionBase::MipsReginfo: + Sec = new MipsReginfoOutputSection(); + break; + case InputSectionBase::MipsOptions: + Sec = new MipsOptionsOutputSection(); + break; + } + return {Sec, true}; +} + +template +OutputSectionBase *OutputSectionFactory::lookup(StringRef Name, + uint32_t Type, + uintX_t Flags) { + return Map.lookup({Name, Type, Flags, 0}); +} + +template +SectionKey +OutputSectionFactory::createKey(InputSectionBase *C, + StringRef OutsecName) { + const Elf_Shdr *H = C->getSectionHdr(); + uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED; + + // For SHF_MERGE we create different output sections for each alignment. + // This makes each output section simple and keeps a single level mapping from + // input to output. + uintX_t Alignment = 0; + if (isa>(C)) + Alignment = std::max(H->sh_addralign, H->sh_entsize); + + uint32_t Type = H->sh_type; + return SectionKey{OutsecName, Type, Flags, Alignment}; +} + +template +typename lld::elf::SectionKey +DenseMapInfo>::getEmptyKey() { + return SectionKey{DenseMapInfo::getEmptyKey(), 0, 0, 0}; +} +template +typename lld::elf::SectionKey +DenseMapInfo>::getTombstoneKey() { + return SectionKey{DenseMapInfo::getTombstoneKey(), 0, 0, + 0}; +} +template +unsigned +DenseMapInfo>::getHashValue(const Key &Val) { + return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment); +} +template +bool DenseMapInfo>::isEqual(const Key &LHS, + const Key &RHS) { + return DenseMapInfo::isEqual(LHS.Name, RHS.Name) && + LHS.Type == RHS.Type && LHS.Flags == RHS.Flags && + LHS.Alignment == RHS.Alignment; +} + +namespace llvm { +template struct DenseMapInfo>; +template struct DenseMapInfo>; +} + namespace lld { namespace elf { template class OutputSectionBase; @@ -1877,5 +1960,10 @@ template class BuildIdHexstring; template class BuildIdHexstring; template class BuildIdHexstring; + +template class OutputSectionFactory; +template class OutputSectionFactory; +template class OutputSectionFactory; +template class OutputSectionFactory; } } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -242,37 +242,6 @@ check(Buffer->commit()); } -namespace { -template struct SectionKey { - typedef typename std::conditional::type uintX_t; - StringRef Name; - uint32_t Type; - uintX_t Flags; - uintX_t Alignment; -}; -} -namespace llvm { -template struct DenseMapInfo> { - static SectionKey getEmptyKey() { - return SectionKey{DenseMapInfo::getEmptyKey(), 0, 0, - 0}; - } - static SectionKey getTombstoneKey() { - return SectionKey{DenseMapInfo::getTombstoneKey(), 0, - 0, 0}; - } - static unsigned getHashValue(const SectionKey &Val) { - return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment); - } - static bool isEqual(const SectionKey &LHS, - const SectionKey &RHS) { - return DenseMapInfo::isEqual(LHS.Name, RHS.Name) && - LHS.Type == RHS.Type && LHS.Flags == RHS.Flags && - LHS.Alignment == RHS.Alignment; - } -}; -} - template static void reportUndefined(SymbolTable &Symtab, SymbolBody *Sym) { if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore) @@ -563,79 +532,6 @@ DefinedSynthetic::SectionEnd); } -// This class knows how to create an output section for a given -// input section. Output section type is determined by various -// factors, including input section's sh_flags, sh_type and -// linker scripts. -namespace { -template class OutputSectionFactory { - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::uint uintX_t; - -public: - std::pair *, bool> create(InputSectionBase *C, - StringRef OutsecName); - - OutputSectionBase *lookup(StringRef Name, uint32_t Type, - uintX_t Flags) { - return Map.lookup({Name, Type, Flags, 0}); - } - -private: - SectionKey createKey(InputSectionBase *C, - StringRef OutsecName); - - SmallDenseMap, OutputSectionBase *> Map; -}; -} - -template -std::pair *, bool> -OutputSectionFactory::create(InputSectionBase *C, - StringRef OutsecName) { - SectionKey Key = createKey(C, OutsecName); - OutputSectionBase *&Sec = Map[Key]; - if (Sec) - return {Sec, false}; - - switch (C->SectionKind) { - case InputSectionBase::Regular: - Sec = new OutputSection(Key.Name, Key.Type, Key.Flags); - break; - case InputSectionBase::EHFrame: - return {Out::EhFrame, false}; - case InputSectionBase::Merge: - Sec = new MergeOutputSection(Key.Name, Key.Type, Key.Flags, - Key.Alignment); - break; - case InputSectionBase::MipsReginfo: - Sec = new MipsReginfoOutputSection(); - break; - case InputSectionBase::MipsOptions: - Sec = new MipsOptionsOutputSection(); - break; - } - return {Sec, true}; -} - -template -SectionKey -OutputSectionFactory::createKey(InputSectionBase *C, - StringRef OutsecName) { - const Elf_Shdr *H = C->getSectionHdr(); - uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED; - - // For SHF_MERGE we create different output sections for each alignment. - // This makes each output section simple and keeps a single level mapping from - // input to output. - uintX_t Alignment = 0; - if (isa>(C)) - Alignment = std::max(H->sh_addralign, H->sh_entsize); - - uint32_t Type = H->sh_type; - return SectionKey{OutsecName, Type, Flags, Alignment}; -} - // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. template void Writer::addReservedSymbols() {