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