diff options
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultLayout.h | 92 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/HeaderChunks.h | 7 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 20 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 78 |
4 files changed, 102 insertions, 95 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index 5758bba71a2..68672ced323 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -146,11 +146,12 @@ public: } }; - // Output Sections contain the map of Sectionnames to a vector of sections, + + // Merged Sections contain the map of Sectionnames to a vector of sections, // that have been merged to form a single section - typedef std::map<StringRef, OutputSection<ELFT> *> OutputSectionMapT; - typedef - typename std::vector<OutputSection<ELFT> *>::iterator OutputSectionIter; + typedef std::map<StringRef, MergedSections<ELFT> *> MergedSectionMapT; + typedef typename std::vector<MergedSections<ELFT> *>::iterator + MergedSectionIter; typedef std::unordered_map<SectionKey, AtomSection<ELFT> *, SectionKeyHash, SectionKeyEq> SectionMapT; @@ -195,9 +196,9 @@ public: ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) override; /// \brief Find an output Section given a section name. - OutputSection<ELFT> *findOutputSection(StringRef name) { - auto iter = _outputSectionMap.find(name); - if (iter == _outputSectionMap.end()) + MergedSections<ELFT> *findOutputSection(StringRef name) { + auto iter = _mergedSectionMap.find(name); + if (iter == _mergedSectionMap.end()) return nullptr; return iter->second; } @@ -208,8 +209,8 @@ public: FindByName(name)); } - // Output sections with the same name into a OutputSection - void createOutputSections(); + // Merge sections with the same name into a MergedSections + void mergeSimilarSections(); void assignSectionsToSegments() override; @@ -249,7 +250,7 @@ public: _programHeader = p; } - inline range<OutputSectionIter> outputSections() { return _outputSections; } + inline range<MergedSectionIter> mergedSections() { return _mergedSections; } inline range<ChunkIter> sections() { return _sections; } @@ -313,12 +314,12 @@ protected: protected: llvm::BumpPtrAllocator _allocator; SectionMapT _sectionMap; - OutputSectionMapT _outputSectionMap; + MergedSectionMapT _mergedSectionMap; AdditionalSegmentMapT _additionalSegmentMap; SegmentMapT _segmentMap; std::vector<Chunk<ELFT> *> _sections; std::vector<Segment<ELFT> *> _segments; - std::vector<OutputSection<ELFT> *> _outputSections; + std::vector<MergedSections<ELFT> *> _mergedSections; ELFHeader<ELFT> *_elfHeader; ProgramHeader<ELFT> *_programHeader; LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _dynamicRelocationTable; @@ -607,24 +608,27 @@ ErrorOr<const lld::AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) } } -/// Output sections with the same name into a OutputSection -template <class ELFT> void DefaultLayout<ELFT>::createOutputSections() { - OutputSection<ELFT> *outputSection; +/// Merge sections with the same name into a MergedSections +template<class ELFT> +void +DefaultLayout<ELFT>::mergeSimilarSections() { + MergedSections<ELFT> *mergedSection; for (auto &si : _sections) { - const std::pair<StringRef, OutputSection<ELFT> *> currentOutputSection( - si->name(), nullptr); - std::pair<typename OutputSectionMapT::iterator, bool> outputSectionInsert( - _outputSectionMap.insert(currentOutputSection)); - if (!outputSectionInsert.second) { - outputSection = outputSectionInsert.first->second; + const std::pair<StringRef, MergedSections<ELFT> *> + currentMergedSections(si->name(), nullptr); + std::pair<typename MergedSectionMapT::iterator, bool> + mergedSectionInsert + (_mergedSectionMap.insert(currentMergedSections)); + if (!mergedSectionInsert.second) { + mergedSection = mergedSectionInsert.first->second; } else { - outputSection = new (_allocator.Allocate<OutputSection<ELFT>>()) - OutputSection<ELFT>(si->name()); - _outputSections.push_back(outputSection); - outputSectionInsert.first->second = outputSection; + mergedSection = new (_allocator.Allocate<MergedSections<ELFT>>()) + MergedSections<ELFT>(si->name()); + _mergedSections.push_back(mergedSection); + mergedSectionInsert.first->second = mergedSection; } - outputSection->appendSection(si); + mergedSection->appendSection(si); } } @@ -636,33 +640,33 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() { [](Chunk<ELFT> *A, Chunk<ELFT> *B) { return A->order() < B->order(); }); - // Create output sections. - createOutputSections(); + // Merge all sections + mergeSimilarSections(); // Set the ordinal after sorting the sections int ordinal = 1; - for (auto osi : _outputSections) { - osi->setOrdinal(ordinal); - for (auto ai : osi->sections()) { + for (auto msi : _mergedSections) { + msi->setOrdinal(ordinal); + for (auto ai : msi->sections()) { ai->setOrdinal(ordinal); } ++ordinal; } - for (auto osi : _outputSections) { - for (auto ai : osi->sections()) { + for (auto msi : _mergedSections) { + for (auto ai : msi->sections()) { if (auto section = dyn_cast<Section<ELFT> >(ai)) { if (!hasOutputSegment(section)) continue; - osi->setLoadableSection(section->isLoadableSection()); + msi->setLoadableSection(section->isLoadableSection()); // Get the segment type for the section int64_t segmentType = getSegmentType(section); - osi->setHasSegment(); + msi->setHasSegment(); section->setSegmentType(segmentType); StringRef segmentName = section->segmentKindToStr(); - int64_t lookupSectionFlag = osi->flags(); + int64_t lookupSectionFlag = msi->flags(); if ((!(lookupSectionFlag & llvm::ELF::SHF_WRITE)) && (_context.mergeRODataToTextSegment())) lookupSectionFlag &= ~llvm::ELF::SHF_EXECINSTR; @@ -800,12 +804,12 @@ DefaultLayout<ELFT>::assignVirtualAddress() { section->assignFileOffsets(section->fileOffset()); } // Set the size of the merged Sections - for (auto osi : _outputSections) { + for (auto msi : _mergedSections) { uint64_t sectionfileoffset = 0; uint64_t startFileOffset = 0; uint64_t sectionsize = 0; bool isFirstSection = true; - for (auto si : osi->sections()) { + for (auto si : msi->sections()) { if (isFirstSection) { startFileOffset = si->fileOffset(); isFirstSection = false; @@ -814,16 +818,16 @@ DefaultLayout<ELFT>::assignVirtualAddress() { sectionsize = si->fileSize(); } sectionsize = (sectionfileoffset - startFileOffset) + sectionsize; - osi->setFileOffset(startFileOffset); - osi->setSize(sectionsize); + msi->setFileOffset(startFileOffset); + msi->setSize(sectionsize); } // Set the virtual addr of the merged Sections - for (auto osi : _outputSections) { + for (auto msi : _mergedSections) { uint64_t sectionstartaddr = 0; uint64_t startaddr = 0; uint64_t sectionsize = 0; bool isFirstSection = true; - for (auto si : osi->sections()) { + for (auto si : msi->sections()) { if (isFirstSection) { startaddr = si->virtualAddr(); isFirstSection = false; @@ -832,8 +836,8 @@ DefaultLayout<ELFT>::assignVirtualAddress() { sectionsize = si->memSize(); } sectionsize = (sectionstartaddr - startaddr) + sectionsize; - osi->setMemSize(sectionsize); - osi->setAddr(startaddr); + msi->setMemSize(sectionsize); + msi->setAddr(startaddr); } } diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h index d21aee377a9..62a4374d015 100644 --- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h +++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h @@ -266,7 +266,7 @@ public: SectionHeader(const ELFLinkingContext &, int32_t order); - void appendSection(OutputSection<ELFT> *section); + void appendSection(MergedSections<ELFT> *section); void updateSection(Section<ELFT> *section); @@ -317,8 +317,9 @@ SectionHeader<ELFT>::SectionHeader(const ELFLinkingContext &context, this->_fsize += sizeof (Elf_Shdr); } -template <class ELFT> -void SectionHeader<ELFT>::appendSection(OutputSection<ELFT> *section) { +template<class ELFT> +void +SectionHeader<ELFT>::appendSection(MergedSections<ELFT> *section) { Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr; shdr->sh_name = _stringSection->addString(section->name()); shdr->sh_type = section->type(); diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index 440187e0a7e..2cb8ded4f1f 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -249,24 +249,24 @@ void OutputELFWriter<ELFT>::buildAtomToAddressMap(const File &file) { template<class ELFT> void OutputELFWriter<ELFT>::buildSectionHeaderTable() { ScopedTask task(getDefaultDomain(), "buildSectionHeaderTable"); - for (auto outputSection : _layout.outputSections()) { - if (outputSection->kind() != Chunk<ELFT>::Kind::ELFSection && - outputSection->kind() != Chunk<ELFT>::Kind::AtomSection) + for (auto mergedSec : _layout.mergedSections()) { + if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection && + mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection) continue; - if (outputSection->hasSegment()) - _shdrtab->appendSection(outputSection); + if (mergedSec->hasSegment()) + _shdrtab->appendSection(mergedSec); } } template<class ELFT> void OutputELFWriter<ELFT>::assignSectionsWithNoSegments() { ScopedTask task(getDefaultDomain(), "assignSectionsWithNoSegments"); - for (auto outputSection : _layout.outputSections()) { - if (outputSection->kind() != Chunk<ELFT>::Kind::ELFSection && - outputSection->kind() != Chunk<ELFT>::Kind::AtomSection) + for (auto mergedSec : _layout.mergedSections()) { + if (mergedSec->kind() != Chunk<ELFT>::Kind::ELFSection && + mergedSec->kind() != Chunk<ELFT>::Kind::AtomSection) continue; - if (!outputSection->hasSegment()) - _shdrtab->appendSection(outputSection); + if (!mergedSec->hasSegment()) + _shdrtab->appendSection(mergedSec); } _layout.assignFileOffsetsForMiscSections(); for (auto sec : _layout.sections()) diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index 8b9e8199dce..fd15f965102 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -31,7 +31,7 @@ namespace lld { namespace elf { -template <class> class OutputSection; +template <class> class MergedSections; using namespace llvm::ELF; template <class ELFT> class Segment; @@ -40,9 +40,9 @@ template <class ELFT> class Section : public Chunk<ELFT> { public: Section(const ELFLinkingContext &context, StringRef name, typename Chunk<ELFT>::Kind k = Chunk<ELFT>::Kind::ELFSection) - : Chunk<ELFT>(name, k, context), _outputSection(nullptr), _flags(0), - _entSize(0), _type(0), _link(0), _info(0), - _isFirstSectionInOutputSection(false), _segmentType(SHT_NULL) {} + : Chunk<ELFT>(name, k, context), _parent(nullptr), _flags(0), _entSize(0), + _type(0), _link(0), _info(0), _isFirstSectionInMerge(false), + _segmentType(SHT_NULL) {} /// \brief Modify the section contents before assigning virtual addresses // or assigning file offsets @@ -95,9 +95,9 @@ public: virtual bool findAtomAddrByName(StringRef, uint64_t &) { return false; } - void setOutputSection(OutputSection<ELFT> *os, bool isFirst = false) { - _outputSection = os; - _isFirstSectionInOutputSection = isFirst; + void setMergedSection(MergedSections<ELFT> *ms, bool isFirst = false) { + _parent = ms; + _isFirstSectionInMerge = isFirst; } static bool classof(const Chunk<ELFT> *c) { @@ -106,13 +106,12 @@ public: } uint64_t align2() const override { - return _isFirstSectionInOutputSection ? _outputSection->align2() - : this->_align2; + return _isFirstSectionInMerge ? _parent->align2() : this->_align2; } protected: - /// \brief OutputSection this Section is a member of, or nullptr. - OutputSection<ELFT> *_outputSection; + /// \brief MergedSections this Section is a member of, or nullptr. + MergedSections<ELFT> *_parent; /// \brief ELF SHF_* flags. uint64_t _flags; /// \brief The size of each entity. @@ -123,8 +122,8 @@ protected: uint32_t _link; /// \brief the sh_info field. uint32_t _info; - /// \brief Is this the first section in the output section. - bool _isFirstSectionInOutputSection; + /// \brief Is this the first section in the merged section list. + bool _isFirstSectionInMerge; /// \brief the output ELF segment type of this section. Layout::SegmentType _segmentType; }; @@ -384,21 +383,22 @@ void AtomSection<ELFT>::write(ELFWriter *writer, TargetLayout<ELFT> &layout, }); } -/// \brief A OutputSection represents a set of sections grouped by the same +/// \brief A MergedSections represents a set of sections grouped by the same /// name. The output file that gets written by the linker has sections grouped /// by similar names -template <class ELFT> class OutputSection { +template<class ELFT> +class MergedSections { public: // Iterators typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter; - OutputSection(StringRef name); + MergedSections(StringRef name); - // Appends a section into the list of sections that are part of this Output + // Appends a section into the list of sections that are part of this Merged // Section void appendSection(Chunk<ELFT> *c); - // Set the OutputSection is associated with a segment + // Set the MergedSections is associated with a segment inline void setHasSegment() { _hasSegment = true; } /// Sets the ordinal @@ -411,13 +411,13 @@ public: _memSize = memsz; } - /// Sets the size fo the output Section. + /// Sets the size fo the merged Section inline void setSize(uint64_t fsiz) { _size = fsiz; } - // The offset of the first section contained in the output section is - // contained here. + // The offset of the first section contained in the merged section is + // contained here inline void setFileOffset(uint64_t foffset) { _fileOffset = foffset; } @@ -445,7 +445,7 @@ public: inline range<ChunkIter> sections() { return _sections; } - // The below functions returns the properties of the OutputSection. + // The below functions returns the properties of the MergeSection inline bool hasSegment() const { return _hasSegment; } inline StringRef name() const { return _name; } @@ -493,14 +493,16 @@ private: std::vector<Chunk<ELFT> *> _sections; }; -/// OutputSection +/// MergedSections template <class ELFT> -OutputSection<ELFT>::OutputSection(StringRef name) +MergedSections<ELFT>::MergedSections(StringRef name) : _name(name), _hasSegment(false), _ordinal(0), _flags(0), _size(0), _memSize(0), _fileOffset(0), _virtualAddr(0), _shInfo(0), _entSize(0), _link(0), _align2(0), _kind(0), _type(0), _isLoadableSection(false) {} -template <class ELFT> void OutputSection<ELFT>::appendSection(Chunk<ELFT> *c) { +template<class ELFT> +void +MergedSections<ELFT>::appendSection(Chunk<ELFT> *c) { if (c->align2() > _align2) _align2 = c->align2(); if (const auto section = dyn_cast<Section<ELFT>>(c)) { @@ -511,7 +513,7 @@ template <class ELFT> void OutputSection<ELFT>::appendSection(Chunk<ELFT> *c) { _type = section->getType(); if (_flags < section->getFlags()) _flags = section->getFlags(); - section->setOutputSection(this, (_sections.size() == 0)); + section->setMergedSection(this, (_sections.size() == 0)); } _kind = c->kind(); _sections.push_back(c); @@ -839,9 +841,9 @@ template <class ELFT> void SymbolTable<ELFT>::finalize(bool sort) { } this->_info = shInfo; this->_link = _stringSection->ordinal(); - if (this->_outputSection) { - this->_outputSection->setInfo(this->_info); - this->_outputSection->setLink(this->_link); + if (this->_parent) { + this->_parent->setInfo(this->_info); + this->_parent->setLink(this->_link); } } @@ -963,8 +965,8 @@ public: virtual void finalize() { this->_link = _symbolTable ? _symbolTable->ordinal() : 0; - if (this->_outputSection) - this->_outputSection->setLink(this->_link); + if (this->_parent) + this->_parent->setLink(this->_link); } virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout, @@ -1130,10 +1132,10 @@ public: StringTable<ELFT> *dynamicStringTable = _dynamicSymbolTable->getStringTable(); this->_link = dynamicStringTable->ordinal(); - if (this->_outputSection) { - this->_outputSection->setType(this->_type); - this->_outputSection->setInfo(this->_info); - this->_outputSection->setLink(this->_link); + if (this->_parent) { + this->_parent->setType(this->_type); + this->_parent->setInfo(this->_info); + this->_parent->setLink(this->_link); } } @@ -1325,8 +1327,8 @@ public: virtual void finalize() { this->_link = _symbolTable ? _symbolTable->ordinal() : 0; - if (this->_outputSection) - this->_outputSection->setLink(this->_link); + if (this->_parent) + this->_parent->setLink(this->_link); } virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout, @@ -1379,7 +1381,7 @@ public: } void finalize() override { - OutputSection<ELFT> *s = _layout.findOutputSection(".eh_frame"); + MergedSections<ELFT> *s = _layout.findOutputSection(".eh_frame"); _ehFrameAddr = s ? s->virtualAddr() : 0; } |