summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-09-13 14:23:14 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-09-13 14:23:14 +0000
commit10897f1807610802f9b5cdc0f6792adece7bfd3f (patch)
tree8452165bc5ae872e256ec0f71674869d54e5a36a /lld/ELF/OutputSections.cpp
parentfbd38cadf16efcb15c09574ccd6844cfb7cfc97c (diff)
downloadbcm5719-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.cpp25
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>();
OpenPOWER on IntegriCloud