1 //===- ELFDynamic.h -------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_TARGET_ELFDYNAMIC_H_ 10 #define MCLD_TARGET_ELFDYNAMIC_H_ 11 12 #include "mcld/LD/LDSection.h" 13 #include "mcld/Support/FileOutputBuffer.h" 14 #include <llvm/Support/ELF.h> 15 #include <vector> 16 #include <cstring> 17 18 namespace mcld { 19 20 class ELFFileFormat; 21 class GNULDBackend; 22 class LinkerConfig; 23 24 namespace elf_dynamic { 25 26 /** \class EntryIF 27 * \brief EntryIF provides a common interface for one entry in the dynamic 28 * section 29 */ 30 class EntryIF { 31 protected: 32 EntryIF(); 33 34 public: 35 virtual ~EntryIF(); 36 37 virtual EntryIF* clone() const = 0; 38 virtual size_t size() const = 0; 39 virtual size_t symbolSize() const = 0; 40 virtual size_t relSize() const = 0; 41 virtual size_t relaSize() const = 0; 42 virtual size_t emit(uint8_t* pAddress) const = 0; 43 virtual void setValue(uint64_t pTag, uint64_t pValue) = 0; 44 }; 45 46 template <size_t BITNUMBER, bool LITTLEENDIAN> 47 class Entry {}; 48 49 template <> 50 class Entry<32, true> : public EntryIF { 51 public: 52 typedef llvm::ELF::Elf32_Dyn Pair; 53 typedef llvm::ELF::Elf32_Sym Symbol; 54 typedef llvm::ELF::Elf32_Rel Rel; 55 typedef llvm::ELF::Elf32_Rela Rela; 56 57 public: 58 inline Entry(); 59 60 inline ~Entry(); 61 clone()62 Entry* clone() const { return new Entry(); } 63 size()64 size_t size() const { return sizeof(Pair); } 65 symbolSize()66 size_t symbolSize() const { return sizeof(Symbol); } 67 relSize()68 size_t relSize() const { return sizeof(Rel); } 69 relaSize()70 size_t relaSize() const { return sizeof(Rela); } 71 72 inline void setValue(uint64_t pTag, uint64_t pValue); 73 74 inline size_t emit(uint8_t* pAddress) const; 75 76 private: 77 Pair m_Pair; 78 }; 79 80 template <> 81 class Entry<64, true> : public EntryIF { 82 public: 83 typedef llvm::ELF::Elf64_Dyn Pair; 84 typedef llvm::ELF::Elf64_Sym Symbol; 85 typedef llvm::ELF::Elf64_Rel Rel; 86 typedef llvm::ELF::Elf64_Rela Rela; 87 88 public: 89 inline Entry(); 90 91 inline ~Entry(); 92 clone()93 Entry* clone() const { return new Entry(); } 94 size()95 size_t size() const { return sizeof(Pair); } 96 symbolSize()97 size_t symbolSize() const { return sizeof(Symbol); } 98 relSize()99 size_t relSize() const { return sizeof(Rel); } 100 relaSize()101 size_t relaSize() const { return sizeof(Rela); } 102 103 inline void setValue(uint64_t pTag, uint64_t pValue); 104 105 inline size_t emit(uint8_t* pAddress) const; 106 107 private: 108 Pair m_Pair; 109 }; 110 111 #include "ELFDynamic.tcc" 112 113 } // namespace elf_dynamic 114 115 /** \class ELFDynamic 116 * \brief ELFDynamic is the .dynamic section in ELF shared and executable 117 * files. 118 */ 119 class ELFDynamic { 120 public: 121 typedef std::vector<elf_dynamic::EntryIF*> EntryListType; 122 typedef EntryListType::iterator iterator; 123 typedef EntryListType::const_iterator const_iterator; 124 125 public: 126 ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig); 127 128 virtual ~ELFDynamic(); 129 130 size_t size() const; 131 132 size_t entrySize() const; 133 134 size_t numOfBytes() const; 135 136 /// reserveEntries - reserve entries 137 void reserveEntries(const ELFFileFormat& pFormat); 138 139 /// reserveNeedEntry - reserve on DT_NEED entry. 140 void reserveNeedEntry(); 141 142 /// applyEntries - apply entries 143 void applyEntries(const ELFFileFormat& pFormat); 144 145 void applySoname(uint64_t pStrTabIdx); 146 needBegin()147 const_iterator needBegin() const { return m_NeedList.begin(); } needBegin()148 iterator needBegin() { return m_NeedList.begin(); } 149 needEnd()150 const_iterator needEnd() const { return m_NeedList.end(); } needEnd()151 iterator needEnd() { return m_NeedList.end(); } 152 153 /// emit 154 void emit(const LDSection& pSection, MemoryRegion& pRegion) const; 155 156 protected: 157 /// reserveTargetEntries - reserve target dependent entries 158 virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0; 159 160 /// applyTargetEntries - apply target-dependant 161 virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0; 162 163 protected: 164 void reserveOne(uint64_t pTag); 165 166 void applyOne(uint64_t pTag, uint64_t pValue); 167 168 size_t symbolSize() const; 169 config()170 const LinkerConfig& config() const { return m_Config; } 171 172 private: 173 EntryListType m_EntryList; 174 EntryListType m_NeedList; 175 elf_dynamic::EntryIF* m_pEntryFactory; 176 const GNULDBackend& m_Backend; 177 const LinkerConfig& m_Config; 178 179 // The entry reserved and the entry being applied are not must matched. 180 // For better performance, we use a simple counter and apply entry one-by-one 181 // by the counter. m_Idx is the counter indicating to the entry being applied. 182 size_t m_Idx; 183 }; 184 185 } // namespace mcld 186 187 #endif // MCLD_TARGET_ELFDYNAMIC_H_ 188