ELFDynamic.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 20namespace mcld 21{ 22 23class GNULDBackend; 24class ELFFileFormat; 25class LinkerConfig; 26class MemoryRegion; 27 28namespace elf_dynamic { 29 30/** \class EntryIF 31* \brief EntryIF provides a common interface for one entry in the dynamic 32* section 33*/ 34class EntryIF 35{ 36protected: 37 EntryIF(); 38 39public: 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 51template<size_t BITNUMBER, bool LITTLEENDIAN> 52class Entry 53{ }; 54 55template<> 56class Entry<32, true> : public EntryIF 57{ 58public: 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 64public: 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 88private: 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 */ 100class ELFDynamic 101{ 102public: 103 typedef std::vector<elf_dynamic::EntryIF*> EntryListType; 104 typedef EntryListType::iterator iterator; 105 typedef EntryListType::const_iterator const_iterator; 106 107public: 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 LinkerConfig& pConfig, 120 const ELFFileFormat& pFormat); 121 122 /// reserveNeedEntry - reserve on DT_NEED entry. 123 void reserveNeedEntry(); 124 125 /// applyEntries - apply entries 126 void applyEntries(const LinkerConfig& pConfig, 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 146protected: 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 153protected: 154 void reserveOne(uint64_t pTag); 155 156 void applyOne(uint64_t pTag, uint64_t pValue); 157 158 size_t symbolSize() const; 159 160private: 161 EntryListType m_EntryList; 162 EntryListType m_NeedList; 163 elf_dynamic::EntryIF* m_pEntryFactory; 164 const GNULDBackend& m_Backend; 165 166 // The entry reserved and the entry being applied are not must matched. 167 // For better performance, we use a simple counter and apply entry one-by-one 168 // by the counter. m_Idx is the counter indicating to the entry being applied. 169 size_t m_Idx; 170}; 171 172} // namespace of mcld 173 174#endif 175 176