diff options
| author | George Rimar <grimar@accesssoftek.com> | 2016-07-12 09:49:43 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2016-07-12 09:49:43 +0000 |
| commit | 6892afaa2df7c88d7913a1253e7b3b810994a9ef (patch) | |
| tree | ee99e02505e563b6da9ff99036820952553b7518 | |
| parent | dc15f1d7b84aa24dc3666f566bff95ebd27cfbbd (diff) | |
| download | bcm5719-llvm-6892afaa2df7c88d7913a1253e7b3b810994a9ef.tar.gz bcm5719-llvm-6892afaa2df7c88d7913a1253e7b3b810994a9ef.zip | |
Recommit r275161 "[ELF] - Move section factory out from writer to make it reusable."
With fix:
* fixed compilation error under linux:
template <class ELFT> class OutputSectionFactory {
...
typedef typename SectionKey<ELFT::Is64Bits> Key;
changed to:
template <class ELFT> class OutputSectionFactory {
...
typedef typename elf::SectionKey<ELFT::Is64Bits> Key;
llvm-svn: 275166
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 91 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 42 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 104 |
3 files changed, 132 insertions, 105 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 3b154bdafde..16833e0aa15 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1751,6 +1751,92 @@ void MipsOptionsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { S->OutSec = this; } +template <class ELFT> +std::pair<OutputSectionBase<ELFT> *, bool> +OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, + StringRef OutsecName) { + SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName); + OutputSectionBase<ELFT> *&Sec = Map[Key]; + if (Sec) + return {Sec, false}; + + switch (C->SectionKind) { + case InputSectionBase<ELFT>::Regular: + Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags); + break; + case InputSectionBase<ELFT>::EHFrame: + return {Out<ELFT>::EhFrame, false}; + case InputSectionBase<ELFT>::Merge: + Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags, + Key.Alignment); + break; + case InputSectionBase<ELFT>::MipsReginfo: + Sec = new MipsReginfoOutputSection<ELFT>(); + break; + case InputSectionBase<ELFT>::MipsOptions: + Sec = new MipsOptionsOutputSection<ELFT>(); + break; + } + return {Sec, true}; +} + +template <class ELFT> +OutputSectionBase<ELFT> *OutputSectionFactory<ELFT>::lookup(StringRef Name, + uint32_t Type, + uintX_t Flags) { + return Map.lookup({Name, Type, Flags, 0}); +} + +template <class ELFT> +SectionKey<ELFT::Is64Bits> +OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *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<MergeInputSection<ELFT>>(C)) + Alignment = std::max(H->sh_addralign, H->sh_entsize); + + uint32_t Type = H->sh_type; + return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, Alignment}; +} + +template <bool Is64Bits> +typename lld::elf::SectionKey<Is64Bits> +DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getEmptyKey() { + return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0, 0}; +} + +template <bool Is64Bits> +typename lld::elf::SectionKey<Is64Bits> +DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getTombstoneKey() { + return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0, + 0}; +} + +template <bool Is64Bits> +unsigned +DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::getHashValue(const Key &Val) { + return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment); +} + +template <bool Is64Bits> +bool DenseMapInfo<lld::elf::SectionKey<Is64Bits>>::isEqual(const Key &LHS, + const Key &RHS) { + return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) && + LHS.Type == RHS.Type && LHS.Flags == RHS.Flags && + LHS.Alignment == RHS.Alignment; +} + +namespace llvm { +template struct DenseMapInfo<SectionKey<true>>; +template struct DenseMapInfo<SectionKey<false>>; +} + namespace lld { namespace elf { template class OutputSectionBase<ELF32LE>; @@ -1877,5 +1963,10 @@ template class BuildIdHexstring<ELF32LE>; template class BuildIdHexstring<ELF32BE>; template class BuildIdHexstring<ELF64LE>; template class BuildIdHexstring<ELF64BE>; + +template class OutputSectionFactory<ELF32LE>; +template class OutputSectionFactory<ELF32BE>; +template class OutputSectionFactory<ELF64LE>; +template class OutputSectionFactory<ELF64BE>; } } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 6e709f357ea..ad7ca7c45a4 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -661,6 +661,35 @@ template <class ELFT> struct Out { static OutputSectionBase<ELFT> *ProgramHeaders; }; +template <bool Is64Bits> struct SectionKey { + typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::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 ELFT> class OutputSectionFactory { + typedef typename ELFT::Shdr Elf_Shdr; + typedef typename ELFT::uint uintX_t; + typedef typename elf::SectionKey<ELFT::Is64Bits> Key; + +public: + std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C, + StringRef OutsecName); + + OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type, uintX_t Flags); + +private: + Key createKey(InputSectionBase<ELFT> *C, StringRef OutsecName); + + llvm::SmallDenseMap<Key, OutputSectionBase<ELFT> *> Map; +}; + template <class ELFT> BuildIdSection<ELFT> *Out<ELFT>::BuildId; template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic; template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr; @@ -692,4 +721,15 @@ template <class ELFT> OutputSectionBase<ELFT> *Out<ELFT>::ProgramHeaders; } // namespace elf } // namespace lld -#endif // LLD_ELF_OUTPUT_SECTIONS_H +namespace llvm { +template <bool Is64Bits> struct DenseMapInfo<lld::elf::SectionKey<Is64Bits>> { + typedef typename lld::elf::SectionKey<Is64Bits> Key; + + static Key getEmptyKey(); + static Key getTombstoneKey(); + static unsigned getHashValue(const Key &Val); + static bool isEqual(const Key &LHS, const Key &RHS); +}; +} + +#endif diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 9d6f42f9548..17b10259d8f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -264,37 +264,6 @@ template <class ELFT> void Writer<ELFT>::run() { check(Buffer->commit()); } -namespace { -template <bool Is64Bits> struct SectionKey { - typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t; - StringRef Name; - uint32_t Type; - uintX_t Flags; - uintX_t Alignment; -}; -} -namespace llvm { -template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> { - static SectionKey<Is64Bits> getEmptyKey() { - return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0, - 0}; - } - static SectionKey<Is64Bits> getTombstoneKey() { - return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0, - 0, 0}; - } - static unsigned getHashValue(const SectionKey<Is64Bits> &Val) { - return hash_combine(Val.Name, Val.Type, Val.Flags, Val.Alignment); - } - static bool isEqual(const SectionKey<Is64Bits> &LHS, - const SectionKey<Is64Bits> &RHS) { - return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) && - LHS.Type == RHS.Type && LHS.Flags == RHS.Flags && - LHS.Alignment == RHS.Alignment; - } -}; -} - template <class ELFT> static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) { if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore) @@ -555,79 +524,6 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() { DefinedSynthetic<ELFT>::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 ELFT> class OutputSectionFactory { - typedef typename ELFT::Shdr Elf_Shdr; - typedef typename ELFT::uint uintX_t; - -public: - std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C, - StringRef OutsecName); - - OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type, - uintX_t Flags) { - return Map.lookup({Name, Type, Flags, 0}); - } - -private: - SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, - StringRef OutsecName); - - SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSectionBase<ELFT> *> Map; -}; -} - -template <class ELFT> -std::pair<OutputSectionBase<ELFT> *, bool> -OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, - StringRef OutsecName) { - SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName); - OutputSectionBase<ELFT> *&Sec = Map[Key]; - if (Sec) - return {Sec, false}; - - switch (C->SectionKind) { - case InputSectionBase<ELFT>::Regular: - Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags); - break; - case InputSectionBase<ELFT>::EHFrame: - return {Out<ELFT>::EhFrame, false}; - case InputSectionBase<ELFT>::Merge: - Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags, - Key.Alignment); - break; - case InputSectionBase<ELFT>::MipsReginfo: - Sec = new MipsReginfoOutputSection<ELFT>(); - break; - case InputSectionBase<ELFT>::MipsOptions: - Sec = new MipsOptionsOutputSection<ELFT>(); - break; - } - return {Sec, true}; -} - -template <class ELFT> -SectionKey<ELFT::Is64Bits> -OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *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<MergeInputSection<ELFT>>(C)) - Alignment = std::max(H->sh_addralign, H->sh_entsize); - - uint32_t Type = H->sh_type; - return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, Alignment}; -} - // The linker is expected to define some symbols depending on // the linking result. This function defines such symbols. template <class ELFT> void Writer<ELFT>::addReservedSymbols() { |

