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