| Shankar Easwaran | 8c55c01 | 2013-02-22 18:01:08 +0000 | [diff] [blame^] | 1 | //===- lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h-----------------===// |
| 2 | // |
| 3 | // The LLVM Linker |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "HexagonTargetHandler.h" |
| 11 | |
| 12 | namespace lld { |
| 13 | namespace elf { |
| 14 | typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType; |
| 15 | template <typename ELFT> class HexagonTargetLayout; |
| 16 | class HexagonTargetInfo; |
| 17 | |
| 18 | /// \brief Handle Hexagon SData section |
| 19 | template <class HexagonELFType> |
| 20 | class SDataSection : public AtomSection<HexagonELFType> { |
| 21 | public: |
| 22 | SDataSection(const HexagonTargetInfo &hti) |
| 23 | : AtomSection<HexagonELFType>( |
| 24 | hti, ".sdata", DefinedAtom::typeDataFast, 0, |
| 25 | HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) { |
| 26 | this->_type = SHT_PROGBITS; |
| 27 | this->_flags = SHF_ALLOC | SHF_WRITE; |
| 28 | } |
| 29 | |
| 30 | /// \brief Finalize the section contents before writing |
| 31 | virtual void doPreFlight(); |
| 32 | |
| 33 | /// \brief Does this section have an output segment. |
| 34 | virtual bool hasOutputSegment() { return true; } |
| 35 | |
| 36 | const AtomLayout &appendAtom(const Atom *atom) { |
| 37 | const DefinedAtom *definedAtom = cast<DefinedAtom>(atom); |
| 38 | DefinedAtom::Alignment atomAlign = definedAtom->alignment(); |
| 39 | uint64_t align2 = 1u << atomAlign.powerOf2; |
| 40 | this->_atoms.push_back(new (this->_alloc) AtomLayout(atom, 0, 0)); |
| 41 | // Set the section alignment to the largest alignment |
| 42 | // std::max doesnot support uint64_t |
| 43 | if (this->_align2 < align2) |
| 44 | this->_align2 = align2; |
| 45 | return *(this->_atoms.back()); |
| 46 | } |
| 47 | |
| 48 | }; // SDataSection |
| 49 | |
| 50 | template <class HexagonELFType> |
| 51 | void SDataSection<HexagonELFType>::doPreFlight() { |
| 52 | // sort the atoms on the alignments they have been set |
| 53 | std::stable_sort(this->_atoms.begin(), this->_atoms.end(), |
| 54 | [](const AtomLayout * A, const AtomLayout * B) { |
| 55 | const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom); |
| 56 | const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom); |
| 57 | int64_t align2A = 1 << definedAtomA->alignment().powerOf2; |
| 58 | int64_t align2B = 1 << definedAtomB->alignment().powerOf2; |
| 59 | return align2A < align2B; |
| 60 | }); |
| 61 | |
| 62 | // Set the fileOffset, and the appropriate size of the section |
| 63 | for (auto &ai : this->_atoms) { |
| 64 | const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom); |
| 65 | DefinedAtom::Alignment atomAlign = definedAtom->alignment(); |
| 66 | uint64_t fOffset = this->alignOffset(this->fileSize(), atomAlign); |
| 67 | uint64_t mOffset = this->alignOffset(this->memSize(), atomAlign); |
| 68 | ai->_fileOffset = fOffset; |
| 69 | this->_fsize = fOffset + definedAtom->size(); |
| 70 | this->_msize = mOffset + definedAtom->size(); |
| 71 | } |
| 72 | } // finalize |
| 73 | |
| 74 | } // elf |
| 75 | } // lld |
| 76 | |