1 //===- X86LDBackend.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 TARGET_X86_X86LDBACKEND_H_ 10 #define TARGET_X86_X86LDBACKEND_H_ 11 12 #include "X86ELFDynamic.h" 13 #include "X86GOT.h" 14 #include "X86GOTPLT.h" 15 #include "X86PLT.h" 16 17 #include "mcld/LD/LDSection.h" 18 #include "mcld/Target/GNULDBackend.h" 19 #include "mcld/Target/OutputRelocSection.h" 20 21 namespace mcld { 22 23 class LinkerConfig; 24 class GNUInfo; 25 26 //===----------------------------------------------------------------------===// 27 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format 28 /// 29 class X86GNULDBackend : public GNULDBackend { 30 public: 31 X86GNULDBackend(const LinkerConfig& pConfig, 32 GNUInfo* pInfo, 33 Relocation::Type pCopyRel); 34 35 ~X86GNULDBackend(); 36 37 uint32_t machine() const; 38 39 X86PLT& getPLT(); 40 41 const X86PLT& getPLT() const; 42 43 /// preLayout - Backend can do any needed modification before layout 44 void doPreLayout(IRBuilder& pBuilder); 45 46 /// postLayout -Backend can do any needed modification after layout 47 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 48 49 /// dynamic - the dynamic section of the target machine. 50 /// Use co-variant return type to return its own dynamic section. 51 X86ELFDynamic& dynamic(); 52 53 /// dynamic - the dynamic section of the target machine. 54 /// Use co-variant return type to return its own dynamic section. 55 const X86ELFDynamic& dynamic() const; 56 57 /// emitSectionData - write out the section data into the memory region. 58 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 59 /// call back target backend to emit the data. 60 /// 61 /// Backends handle the target-special tables (plt, gp,...) by themselves. 62 /// Backend can put the data of the tables in MCSectionData directly 63 /// - LDSection.getSectionData can get the section data. 64 /// Or, backend can put the data into special data structure 65 /// - backend can maintain its own map<LDSection, table> to get the table 66 /// from given LDSection. 67 /// 68 /// @param pSection - the given LDSection 69 /// @param pLayout - for comouting the size of fragment 70 /// @param pRegion - the region to write out data 71 /// @return the size of the table in the file. 72 uint64_t emitSectionData(const LDSection& pSection, 73 MemoryRegion& pRegion) const; 74 75 /// initRelocator - create and initialize Relocator. 76 virtual bool initRelocator() = 0; 77 78 /// getRelocator - return relocator. 79 const Relocator* getRelocator() const; 80 Relocator* getRelocator(); 81 82 virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) = 0; 83 84 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 85 86 OutputRelocSection& getRelDyn(); 87 const OutputRelocSection& getRelDyn() const; 88 89 OutputRelocSection& getRelPLT(); 90 const OutputRelocSection& getRelPLT() const; 91 getGOTSymbol()92 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } getGOTSymbol()93 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 94 95 /// getTargetSectionOrder - compute the layout order of X86 target sections 96 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 97 98 /// finalizeTargetSymbols - finalize the symbol value 99 bool finalizeTargetSymbols(); 100 101 /// getPointerRel - get pointer relocation type. getPointerRel()102 Relocation::Type getPointerRel() { return m_PointerRel; } 103 getCopyRelType()104 Relocation::Type getCopyRelType() const { return m_CopyRel; } getPointerRelType()105 Relocation::Type getPointerRelType() const { return m_PointerRel; } 106 107 protected: 108 void defineGOTSymbol(IRBuilder& pBuilder, Fragment&); 109 110 /// getRelEntrySize - the size in BYTE of rel type relocation getRelEntrySize()111 size_t getRelEntrySize() { return m_RelEntrySize; } 112 113 /// getRelEntrySize - the size in BYTE of rela type relocation getRelaEntrySize()114 size_t getRelaEntrySize() { return m_RelaEntrySize; } 115 116 private: 117 /// doCreateProgramHdrs - backend can implement this function to create the 118 /// target-dependent segments 119 void doCreateProgramHdrs(Module& pModule); 120 121 virtual void setGOTSectionSize(IRBuilder& pBuilder) = 0; 122 123 virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const = 0; 124 125 virtual uint64_t emitGOTPLTSectionData( 126 MemoryRegion& pRegion, 127 const ELFFileFormat* FileFormat) const = 0; 128 129 virtual void setRelDynSize() = 0; 130 virtual void setRelPLTSize() = 0; 131 132 void addEhFrameForPLT(Module& pModule); 133 virtual llvm::StringRef createCIERegionForPLT() = 0; 134 virtual llvm::StringRef createFDERegionForPLT() = 0; 135 136 protected: 137 Relocator* m_pRelocator; 138 X86PLT* m_pPLT; 139 /// m_RelDyn - dynamic relocation table of .rel.dyn 140 OutputRelocSection* m_pRelDyn; 141 /// m_RelPLT - dynamic relocation table of .rel.plt 142 OutputRelocSection* m_pRelPLT; 143 144 X86ELFDynamic* m_pDynamic; 145 LDSymbol* m_pGOTSymbol; 146 147 size_t m_RelEntrySize; 148 size_t m_RelaEntrySize; 149 150 Relocation::Type m_CopyRel; 151 Relocation::Type m_PointerRel; 152 }; 153 154 // 155 //===----------------------------------------------------------------------===// 156 /// X86_32GNULDBackend - linker backend of X86-32 target of GNU ELF format 157 /// 158 class X86_32GNULDBackend : public X86GNULDBackend { 159 public: 160 X86_32GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 161 162 ~X86_32GNULDBackend(); 163 164 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 165 166 X86_32GOT& getGOT(); 167 168 const X86_32GOT& getGOT() const; 169 170 X86_32GOTPLT& getGOTPLT(); 171 172 const X86_32GOTPLT& getGOTPLT() const; 173 174 private: 175 /// initRelocator - create and initialize Relocator. 176 bool initRelocator(); 177 178 void setGOTSectionSize(IRBuilder& pBuilder); 179 180 uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 181 182 uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 183 const ELFFileFormat* FileFormat) const; 184 185 void setRelDynSize(); 186 void setRelPLTSize(); 187 188 llvm::StringRef createCIERegionForPLT(); 189 llvm::StringRef createFDERegionForPLT(); 190 191 private: 192 X86_32GOT* m_pGOT; 193 X86_32GOTPLT* m_pGOTPLT; 194 }; 195 196 // 197 //===----------------------------------------------------------------------===// 198 /// X86_64GNULDBackend - linker backend of X86-64 target of GNU ELF format 199 /// 200 class X86_64GNULDBackend : public X86GNULDBackend { 201 public: 202 X86_64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 203 204 ~X86_64GNULDBackend(); 205 206 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 207 208 X86_64GOT& getGOT(); 209 210 const X86_64GOT& getGOT() const; 211 212 X86_64GOTPLT& getGOTPLT(); 213 214 const X86_64GOTPLT& getGOTPLT() const; 215 216 private: 217 /// initRelocator - create and initialize Relocator. 218 bool initRelocator(); 219 220 void setGOTSectionSize(IRBuilder& pBuilder); 221 222 uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 223 224 uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 225 const ELFFileFormat* FileFormat) const; 226 227 void setRelDynSize(); 228 void setRelPLTSize(); 229 230 llvm::StringRef createCIERegionForPLT(); 231 llvm::StringRef createFDERegionForPLT(); 232 233 private: 234 X86_64GOT* m_pGOT; 235 X86_64GOTPLT* m_pGOTPLT; 236 }; 237 238 } // namespace mcld 239 240 #endif // TARGET_X86_X86LDBACKEND_H_ 241