From 8290274c13e287e0a037a05d32d2c039b0092e70 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 16 Feb 2017 17:32:26 +0000 Subject: [PATCH] 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 --- lld/ELF/LinkerScript.cpp | 16 ++----------- lld/ELF/LinkerScript.h | 2 -- lld/ELF/OutputSections.cpp | 49 ++++++++++++++++++++++---------------- lld/ELF/OutputSections.h | 7 +++--- 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 193883ae8875..ead231b8f7dc 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -302,18 +302,6 @@ LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) { return Ret; } -template -void LinkerScript::addSection(OutputSectionFactory &Factory, - InputSectionBase *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 void LinkerScript::processCommands(OutputSectionFactory &Factory) { for (unsigned I = 0; I < Opt.Commands.size(); ++I) { @@ -377,7 +365,7 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { // Add input sections to an output section. for (InputSectionBase *S : V) - addSection(Factory, S, Cmd->Name); + Factory.addInputSec(S, Cmd->Name); } } } @@ -388,7 +376,7 @@ void LinkerScript::addOrphanSections( OutputSectionFactory &Factory) { for (InputSectionBase *S : Symtab::X->Sections) if (S->Live && !S->OutSec) - addSection(Factory, S, getOutputSectionName(S->Name)); + Factory.addInputSec(S, getOutputSectionName(S->Name)); } template static bool isTbss(OutputSectionBase *Sec) { diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 487f4943ab49..9eda62956016 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -277,8 +277,6 @@ public: private: void computeInputSections(InputSectionDescription *); - void addSection(OutputSectionFactory &Factory, - InputSectionBase *Sec, StringRef Name); void discard(ArrayRef *> V); std::vector *> diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index d1f760d3481c..b9d6f403b34d 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -554,10 +554,10 @@ static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) { return SectionKey{OutsecName, Flags, Alignment}; } -template OutputSectionFactory::OutputSectionFactory() {} - -template OutputSectionFactory::~OutputSectionFactory() {} - +template +OutputSectionFactory::OutputSectionFactory( + std::vector &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 -std::pair -OutputSectionFactory::create(InputSectionBase *C, - StringRef OutsecName) { - SectionKey Key = createKey(C, OutsecName); - uintX_t Flags = getOutFlags(C); +void OutputSectionFactory::addInputSec(InputSectionBase *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::EHFrame) { + Out::EhFrame->addSection(IS); + return; + } + Sec = make>(Key.Name, Type, Flags); + OutputSections.push_back(Sec); } - uint32_t Type = C->Type; - if (C->kind() == InputSectionBase::EHFrame) - return {Out::EhFrame, false}; - Sec = make>(Key.Name, Type, Flags); - return {Sec, true}; + Sec->addSection(IS); } +template OutputSectionFactory::~OutputSectionFactory() {} + SectionKey DenseMapInfo::getEmptyKey() { return SectionKey{DenseMapInfo::getEmptyKey(), 0, 0}; } diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 6055e5f2919f..0805df86d7f1 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -212,12 +212,13 @@ template class OutputSectionFactory { typedef typename ELFT::uint uintX_t; public: - OutputSectionFactory(); + OutputSectionFactory(std::vector &OutputSections); ~OutputSectionFactory(); - std::pair create(InputSectionBase *C, - StringRef OutsecName); + void addInputSec(InputSectionBase *IS, StringRef OutsecName); + private: llvm::SmallDenseMap Map; + std::vector &OutputSections; }; template uint64_t getHeaderSize() { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 3cb233290e1e..7ae8a5e39fdc 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 *S); void createSections(); void forEachRelSec(std::function &)> Fn); void sortSections(); @@ -79,7 +78,7 @@ private: std::unique_ptr Buffer; std::vector OutputSections; - OutputSectionFactory Factory; + OutputSectionFactory Factory{OutputSections}; void addRelIpltSymbols(); void addStartEndSymbols(); @@ -918,27 +917,10 @@ void Writer::forEachRelSec( } } -template -void Writer::addInputSec(InputSectionBase *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 void Writer::createSections() { for (InputSectionBase *IS : Symtab::X->Sections) - addInputSec(IS); + if (IS) + Factory.addInputSec(IS, getOutputSectionName(IS->Name)); sortBySymbolsOrder(OutputSections); sortInitFini(findSection(".init_array"));