diff options
| author | Shankar Easwaran <shankare@codeaurora.org> | 2013-02-22 18:01:08 +0000 |
|---|---|---|
| committer | Shankar Easwaran <shankare@codeaurora.org> | 2013-02-22 18:01:08 +0000 |
| commit | 8c55c01d2a68cac0fa31bcc5150f715a94a6b549 (patch) | |
| tree | 14ffb603819efe065e658673d700d9cc27e65f98 | |
| parent | db1a47706bc4d849b5492e2beb066e538a8c4a84 (diff) | |
| download | bcm5719-llvm-8c55c01d2a68cac0fa31bcc5150f715a94a6b549.tar.gz bcm5719-llvm-8c55c01d2a68cac0fa31bcc5150f715a94a6b549.zip | |
sort quickdata for the hexagon target
llvm-svn: 175904
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Chunk.h | 4 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultLayout.h | 5 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/HeaderChunks.h | 24 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h | 76 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h | 61 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 13 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/SegmentChunks.h | 5 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Writer.cpp | 9 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon | bin | 0 -> 1385 bytes | |||
| -rw-r--r-- | lld/test/elf/hexagon-quickdata-sort.test | 12 |
10 files changed, 185 insertions, 24 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Chunk.h b/lld/lib/ReaderWriter/ELF/Chunk.h index 732403b3328..92c3a118ecc 100644 --- a/lld/lib/ReaderWriter/ELF/Chunk.h +++ b/lld/lib/ReaderWriter/ELF/Chunk.h @@ -69,9 +69,11 @@ public: uint64_t virtualAddr() const { return _start; } // Does the chunk occupy memory during execution ? uint64_t memSize() const { return _msize; } - void setMemSize(uint64_t msize) { _msize = msize; } + void setMemSize(uint64_t msize) { _msize = msize; } // Writer the chunk virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0; + // Finalize the chunk before assigning offsets/virtual addresses + virtual void doPreFlight() = 0; // Finalize the chunk before writing virtual void finalize() = 0; diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index d2bdca55c81..a3dad87e2b5 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -208,6 +208,11 @@ public: si->finalize(); } + inline void doPreFlight() { + for (auto &si : _sections) + si->doPreFlight(); + } + inline bool findAtomAddrByName(StringRef name, uint64_t &addr) { for (auto sec : _sections) if (auto section = dyn_cast<Section<ELFT> >(sec)) diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h index 84bcde9f631..6282ee916ce 100644 --- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h +++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h @@ -52,7 +52,9 @@ public: void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer); - void finalize() { } + virtual void doPreFlight() {} + + void finalize() {} private: Elf_Ehdr _eh; @@ -145,11 +147,11 @@ public: return _ph.end(); } - void finalize() { } + virtual void doPreFlight() {} - int64_t entsize() { - return sizeof(Elf_Phdr); - } + void finalize() {} + + int64_t entsize() { return sizeof(Elf_Phdr); } int64_t numHeaders() { return _ph.size(); @@ -249,12 +251,12 @@ public: } void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer); - - void finalize() { } - - inline uint16_t fileSize() { - return sizeof(Elf_Shdr) * _sectionInfo.size(); - } + + virtual void doPreFlight() {} + + void finalize() {} + + inline uint16_t fileSize() { return sizeof(Elf_Shdr) * _sectionInfo.size(); } inline int64_t entsize() { return sizeof(Elf_Shdr); diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h new file mode 100644 index 00000000000..ec81e31b0a1 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h @@ -0,0 +1,76 @@ +//===- lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h-----------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "HexagonTargetHandler.h" + +namespace lld { +namespace elf { +typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType; +template <typename ELFT> class HexagonTargetLayout; +class HexagonTargetInfo; + +/// \brief Handle Hexagon SData section +template <class HexagonELFType> +class SDataSection : public AtomSection<HexagonELFType> { +public: + SDataSection(const HexagonTargetInfo &hti) + : AtomSection<HexagonELFType>( + hti, ".sdata", DefinedAtom::typeDataFast, 0, + HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) { + this->_type = SHT_PROGBITS; + this->_flags = SHF_ALLOC | SHF_WRITE; + } + + /// \brief Finalize the section contents before writing + virtual void doPreFlight(); + + /// \brief Does this section have an output segment. + virtual bool hasOutputSegment() { return true; } + + const AtomLayout &appendAtom(const Atom *atom) { + const DefinedAtom *definedAtom = cast<DefinedAtom>(atom); + DefinedAtom::Alignment atomAlign = definedAtom->alignment(); + uint64_t align2 = 1u << atomAlign.powerOf2; + this->_atoms.push_back(new (this->_alloc) AtomLayout(atom, 0, 0)); + // Set the section alignment to the largest alignment + // std::max doesnot support uint64_t + if (this->_align2 < align2) + this->_align2 = align2; + return *(this->_atoms.back()); + } + +}; // SDataSection + +template <class HexagonELFType> +void SDataSection<HexagonELFType>::doPreFlight() { + // sort the atoms on the alignments they have been set + std::stable_sort(this->_atoms.begin(), this->_atoms.end(), + [](const AtomLayout * A, const AtomLayout * B) { + const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom); + const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom); + int64_t align2A = 1 << definedAtomA->alignment().powerOf2; + int64_t align2B = 1 << definedAtomB->alignment().powerOf2; + return align2A < align2B; + }); + + // Set the fileOffset, and the appropriate size of the section + for (auto &ai : this->_atoms) { + const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom); + DefinedAtom::Alignment atomAlign = definedAtom->alignment(); + uint64_t fOffset = this->alignOffset(this->fileSize(), atomAlign); + uint64_t mOffset = this->alignOffset(this->memSize(), atomAlign); + ai->_fileOffset = fOffset; + this->_fsize = fOffset + definedAtom->size(); + this->_msize = mOffset + definedAtom->size(); + } +} // finalize + +} // elf +} // lld + diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h index 41a620f10a0..b1169cdaf94 100644 --- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h @@ -13,6 +13,7 @@ #include "DefaultTargetHandler.h" #include "ExecutableAtoms.h" #include "HexagonRelocationHandler.h" +#include "HexagonSectionChunks.h" #include "TargetLayout.h" namespace lld { @@ -75,6 +76,64 @@ public: } }; +/// \brief TargetLayout for Hexagon +template <class HexagonELFType> +class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> { + +public: + enum HexagonSectionOrder { + ORDER_SDATA = 205 + }; + + HexagonTargetLayout(const HexagonTargetInfo &hti) + : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) { + _sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti); + } + + /// \brief Return the section order for a input section + virtual Layout::SectionOrder getSectionOrder( + StringRef name, int32_t contentType, int32_t contentPermissions) { + if (contentType == DefinedAtom::typeDataFast) + return ORDER_SDATA; + + return DefaultLayout<HexagonELFType>::getSectionOrder(name, contentType, + contentPermissions); + } + + /// \brief This maps the input sections to the output section names + virtual StringRef getSectionName(StringRef name, const int32_t contentType, + const int32_t contentPermissions) { + if (contentType == DefinedAtom::typeDataFast) + return ".sdata"; + return DefaultLayout<HexagonELFType>::getSectionName(name, contentType, + contentPermissions); + } + + /// \brief Gets or creates a section. + virtual AtomSection<HexagonELFType> * + createSection(StringRef name, int32_t contentType, + DefinedAtom::ContentPermissions contentPermissions, + Layout::SectionOrder sectionOrder) { + if (contentType == DefinedAtom::typeDataFast) + return _sdataSection; + return DefaultLayout<HexagonELFType>::createSection( + name, contentType, contentPermissions, sectionOrder); + } + + /// \brief get the segment type for the section thats defined by the target + virtual Layout::SegmentType + getSegmentType(Section<HexagonELFType> *section) const { + if (section->order() == ORDER_SDATA) + return PT_LOAD; + + return DefaultLayout<HexagonELFType>::getSegmentType(section); + } + +private: + llvm::BumpPtrAllocator _alloc; + SDataSection<HexagonELFType> *_sdataSection; +}; + /// \brief TargetHandler for Hexagon class HexagonTargetHandler LLVM_FINAL : public DefaultTargetHandler<HexagonELFType> { @@ -95,7 +154,7 @@ public: private: HexagonTargetRelocationHandler _relocationHandler; - TargetLayout<HexagonELFType> _targetLayout; + HexagonTargetLayout<HexagonELFType> _targetLayout; HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler; }; } // end namespace elf diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index 118de402982..8b4c87b6916 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -39,13 +39,12 @@ public: /// \param type the ELF SHT_* type of the section. Section(const ELFTargetInfo &ti, StringRef name, typename Chunk<ELFT>::Kind k = Chunk<ELFT>::K_ELFSection) - : Chunk<ELFT>(name, k, ti), - _flags(0), - _entSize(0), - _type(0), - _link(0), - _info(0), - _segmentType(SHT_NULL) {} + : Chunk<ELFT>(name, k, ti), _flags(0), _entSize(0), _type(0), _link(0), + _info(0), _segmentType(SHT_NULL) {} + + /// \brief Modify the section contents before assigning virtual addresses + // or assigning file offsets + virtual void doPreFlight() {} /// \brief Finalize the section contents before writing virtual void finalize() {} diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h index 9be989a707b..fb772dd73ea 100644 --- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h +++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h @@ -159,8 +159,11 @@ public: _sections.insert(_sections.begin(), c); } + // Finalize the segment before assigning File Offsets / Virtual addresses + inline void doPreFlight() {} + // Finalize the segment, before we want to write to the output file - inline void finalize() { } + inline void finalize() {} // For LLVM RTTI static inline bool classof(const Chunk<ELFT> *c) { diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp index 0cd0e550420..4272eb85873 100644 --- a/lld/lib/ReaderWriter/ELF/Writer.cpp +++ b/lld/lib/ReaderWriter/ELF/Writer.cpp @@ -231,11 +231,14 @@ void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() { (*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz; } -template<class ELFT> -error_code -ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { +template <class ELFT> +error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) { buildChunks(file); + // Call the preFlight callbacks to modify the sections and the atoms + // contained in them, in anyway the targets may want + _layout->doPreFlight(); + // Create the default sections like the symbol table, string table, and the // section string table createDefaultSections(); diff --git a/lld/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon b/lld/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon Binary files differnew file mode 100644 index 00000000000..03d02870712 --- /dev/null +++ b/lld/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon diff --git a/lld/test/elf/hexagon-quickdata-sort.test b/lld/test/elf/hexagon-quickdata-sort.test new file mode 100644 index 00000000000..c53b18647e8 --- /dev/null +++ b/lld/test/elf/hexagon-quickdata-sort.test @@ -0,0 +1,12 @@ +RUN: lld-core -arch hexagon -reader ELF %p/Inputs/quickdata-sort-test.o.elf-hexagon -writer ELF -o %t1 +RUN: llvm-nm -n %t1 | FileCheck %s -check-prefix=quickdataSort + +quickdataSort: 00002000 D A1 +quickdataSort: 00002001 D AA1 +quickdataSort: 00002002 D B1 +quickdataSort: 00002004 D BB1 +quickdataSort: 00002008 D C1 +quickdataSort: 0000200c D CC1 +quickdataSort: 00002010 D D1 +quickdataSort: 00002018 D DD1 + |

