diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-09-13 14:23:14 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-09-13 14:23:14 +0000 |
| commit | 10897f1807610802f9b5cdc0f6792adece7bfd3f (patch) | |
| tree | 8452165bc5ae872e256ec0f71674869d54e5a36a /lld/ELF/OutputSections.cpp | |
| parent | fbd38cadf16efcb15c09574ccd6844cfb7cfc97c (diff) | |
| download | bcm5719-llvm-10897f1807610802f9b5cdc0f6792adece7bfd3f.tar.gz bcm5719-llvm-10897f1807610802f9b5cdc0f6792adece7bfd3f.zip | |
Enable merging of SHF_MERGE sections with linker scripts.
This also fixes the related problem of non SHF_MERGE sections with
different flags not being merged.
Fixes pr30355.
llvm-svn: 281338
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index ce5bac9deb1..c984cb11cde 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1831,11 +1831,16 @@ void MipsAbiFlagsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) { } template <class ELFT> +static typename ELFT::uint getOutFlags(InputSectionBase<ELFT> *S) { + return S->getSectionHdr()->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED; +} + +template <class ELFT> static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C, StringRef OutsecName) { const typename ELFT::Shdr *H = C->getSectionHdr(); typedef typename ELFT::uint uintX_t; - uintX_t Flags = H->sh_flags & ~SHF_GROUP & ~SHF_COMPRESSED; + uintX_t Flags = getOutFlags(C); // For SHF_MERGE we create different output sections for each alignment. // This makes each output section simple and keeps a single level mapping from @@ -1853,19 +1858,29 @@ std::pair<OutputSectionBase<ELFT> *, bool> OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, StringRef OutsecName) { SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName); + return create(Key, C); +} + +template <class ELFT> +std::pair<OutputSectionBase<ELFT> *, bool> +OutputSectionFactory<ELFT>::create(const SectionKey<ELFT::Is64Bits> &Key, + InputSectionBase<ELFT> *C) { + uintX_t Flags = getOutFlags(C); OutputSectionBase<ELFT> *&Sec = Map[Key]; - if (Sec) + if (Sec) { + Sec->updateFlags(Flags); return {Sec, false}; + } + uint32_t Type = C->getSectionHdr()->sh_type; switch (C->kind()) { case InputSectionBase<ELFT>::Regular: - Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags); + Sec = new OutputSection<ELFT>(Key.Name, Type, 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); + Sec = new MergeOutputSection<ELFT>(Key.Name, Type, Flags, Key.Alignment); break; case InputSectionBase<ELFT>::MipsReginfo: Sec = new MipsReginfoOutputSection<ELFT>(); |

