diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-16 17:32:26 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-16 17:32:26 +0000 |
| commit | 8290274c13e287e0a037a05d32d2c039b0092e70 (patch) | |
| tree | 27a275ac03ee9718d2be7bc40fbc0f96bbc51ed9 | |
| parent | ad3f63986dd4a941b7716f2bb6cc5d71032ee3b5 (diff) | |
| download | bcm5719-llvm-8290274c13e287e0a037a05d32d2c039b0092e70.tar.gz bcm5719-llvm-8290274c13e287e0a037a05d32d2c039b0092e70.zip | |
Share more output section creation code.
We can do this now that the linker script and the writer agree on
which sections should be combined.
llvm-svn: 295341
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 16 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.h | 2 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 49 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 7 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 24 |
5 files changed, 38 insertions, 60 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 193883ae887..ead231b8f7d 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -303,18 +303,6 @@ LinkerScript<ELFT>::createInputSectionList(OutputSectionCommand &OutCmd) { } template <class ELFT> -void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory, - InputSectionBase<ELFT> *Sec, - StringRef Name) { - OutputSectionBase *OutSec; - bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(Sec, Name); - if (IsNew) - OutputSections->push_back(OutSec); - OutSec->addSection(Sec); -} - -template <class ELFT> void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { for (unsigned I = 0; I < Opt.Commands.size(); ++I) { auto Iter = Opt.Commands.begin() + I; @@ -377,7 +365,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { // Add input sections to an output section. for (InputSectionBase<ELFT> *S : V) - addSection(Factory, S, Cmd->Name); + Factory.addInputSec(S, Cmd->Name); } } } @@ -388,7 +376,7 @@ void LinkerScript<ELFT>::addOrphanSections( OutputSectionFactory<ELFT> &Factory) { for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) if (S->Live && !S->OutSec) - addSection(Factory, S, getOutputSectionName(S->Name)); + Factory.addInputSec(S, getOutputSectionName(S->Name)); } template <class ELFT> static bool isTbss(OutputSectionBase *Sec) { diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 487f4943ab4..9eda6295601 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -277,8 +277,6 @@ public: private: void computeInputSections(InputSectionDescription *); - void addSection(OutputSectionFactory<ELFT> &Factory, - InputSectionBase<ELFT> *Sec, StringRef Name); void discard(ArrayRef<InputSectionBase<ELFT> *> V); std::vector<InputSectionBase<ELFT> *> diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index d1f760d3481..b9d6f403b34 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -554,10 +554,10 @@ static SectionKey createKey(InputSectionBase<ELFT> *C, StringRef OutsecName) { return SectionKey{OutsecName, Flags, Alignment}; } -template <class ELFT> OutputSectionFactory<ELFT>::OutputSectionFactory() {} - -template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {} - +template <class ELFT> +OutputSectionFactory<ELFT>::OutputSectionFactory( + std::vector<OutputSectionBase *> &OutputSections) + : OutputSections(OutputSections) {} static uint64_t getIncompatibleFlags(uint64_t Flags) { return Flags & (SHF_ALLOC | SHF_TLS); @@ -576,34 +576,43 @@ static bool canMergeToProgbits(unsigned Type) { } template <class ELFT> -std::pair<OutputSectionBase *, bool> -OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C, - StringRef OutsecName) { - SectionKey Key = createKey(C, OutsecName); - uintX_t Flags = getOutFlags(C); +void OutputSectionFactory<ELFT>::addInputSec(InputSectionBase<ELFT> *IS, + StringRef OutsecName) { + if (!IS->Live) { + reportDiscarded(IS); + return; + } + + SectionKey Key = createKey(IS, OutsecName); + uintX_t Flags = getOutFlags(IS); OutputSectionBase *&Sec = Map[Key]; if (Sec) { - if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags)) + if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("Section has flags incompatible with others with the same name " + - toString(C)); - if (Sec->Type != C->Type) { - if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(C->Type)) + toString(IS)); + if (Sec->Type != IS->Type) { + if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type)) Sec->Type = SHT_PROGBITS; else error("Section has different type from others with the same name " + - toString(C)); + toString(IS)); } Sec->Flags |= Flags; - return {Sec, false}; + } else { + uint32_t Type = IS->Type; + if (IS->kind() == InputSectionBase<ELFT>::EHFrame) { + Out<ELFT>::EhFrame->addSection(IS); + return; + } + Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags); + OutputSections.push_back(Sec); } - uint32_t Type = C->Type; - if (C->kind() == InputSectionBase<ELFT>::EHFrame) - return {Out<ELFT>::EhFrame, false}; - Sec = make<OutputSection<ELFT>>(Key.Name, Type, Flags); - return {Sec, true}; + Sec->addSection(IS); } +template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {} + SectionKey DenseMapInfo<SectionKey>::getEmptyKey() { return SectionKey{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0}; } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 6055e5f2919..0805df86d7f 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -212,12 +212,13 @@ template <class ELFT> class OutputSectionFactory { typedef typename ELFT::uint uintX_t; public: - OutputSectionFactory(); + OutputSectionFactory(std::vector<OutputSectionBase *> &OutputSections); ~OutputSectionFactory(); - std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C, - StringRef OutsecName); + void addInputSec(InputSectionBase<ELFT> *IS, StringRef OutsecName); + private: llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map; + std::vector<OutputSectionBase *> &OutputSections; }; template <class ELFT> uint64_t getHeaderSize() { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 3cb233290e1..7ae8a5e39fd 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -53,7 +53,6 @@ private: void copyLocalSymbols(); void addSectionSymbols(); void addReservedSymbols(); - void addInputSec(InputSectionBase<ELFT> *S); void createSections(); void forEachRelSec(std::function<void(InputSectionBase<ELFT> &)> Fn); void sortSections(); @@ -79,7 +78,7 @@ private: std::unique_ptr<FileOutputBuffer> Buffer; std::vector<OutputSectionBase *> OutputSections; - OutputSectionFactory<ELFT> Factory; + OutputSectionFactory<ELFT> Factory{OutputSections}; void addRelIpltSymbols(); void addStartEndSymbols(); @@ -918,27 +917,10 @@ void Writer<ELFT>::forEachRelSec( } } -template <class ELFT> -void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) { - if (!IS) - return; - - if (!IS->Live) { - reportDiscarded(IS); - return; - } - OutputSectionBase *Sec; - bool IsNew; - StringRef OutsecName = getOutputSectionName(IS->Name); - std::tie(Sec, IsNew) = Factory.create(IS, OutsecName); - if (IsNew) - OutputSections.push_back(Sec); - Sec->addSection(IS); -} - template <class ELFT> void Writer<ELFT>::createSections() { for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) - addInputSec(IS); + if (IS) + Factory.addInputSec(IS, getOutputSectionName(IS->Name)); sortBySymbolsOrder<ELFT>(OutputSections); sortInitFini<ELFT>(findSection(".init_array")); |

