X86LDBackend.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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 X86_LDBACKEND_H 10#define X86_LDBACKEND_H 11 12#include "X86ELFDynamic.h" 13#include "X86GOT.h" 14#include "X86GOTPLT.h" 15#include "X86PLT.h" 16#include <mcld/LD/LDSection.h> 17#include <mcld/Target/GNULDBackend.h> 18#include <mcld/Target/OutputRelocSection.h> 19 20namespace mcld { 21 22class LinkerConfig; 23class GNUInfo; 24 25//===----------------------------------------------------------------------===// 26/// X86GNULDBackend - linker backend of X86 target of GNU ELF format 27/// 28class X86GNULDBackend : public GNULDBackend 29{ 30public: 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 Relocator* getRelocator(); 80 81 virtual void initTargetSections(Module& pModule, ObjectBuilder& pBuilder) = 0; 82 83 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 84 85 OutputRelocSection& getRelDyn(); 86 const OutputRelocSection& getRelDyn() const; 87 88 OutputRelocSection& getRelPLT(); 89 const OutputRelocSection& getRelPLT() const; 90 91 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 92 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 93 94 /// getTargetSectionOrder - compute the layout order of X86 target sections 95 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 96 97 /// finalizeTargetSymbols - finalize the symbol value 98 bool finalizeTargetSymbols(); 99 100 /// getPointerRel - get pointer relocation type. 101 Relocation::Type getPointerRel() 102 { return m_PointerRel; } 103 104 Relocation::Type getCopyRelType() const { return m_CopyRel; } 105 Relocation::Type getPointerRelType() const { return m_PointerRel; } 106 107protected: 108 void defineGOTSymbol(IRBuilder& pBuilder, Fragment&); 109 110 /// getRelEntrySize - the size in BYTE of rel type relocation 111 size_t getRelEntrySize() 112 { return m_RelEntrySize; } 113 114 /// getRelEntrySize - the size in BYTE of rela type relocation 115 size_t getRelaEntrySize() 116 { return m_RelaEntrySize; } 117 118private: 119 /// doCreateProgramHdrs - backend can implement this function to create the 120 /// target-dependent segments 121 void doCreateProgramHdrs(Module& pModule); 122 123 virtual void setGOTSectionSize(IRBuilder& pBuilder) = 0; 124 125 virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const = 0; 126 127 virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 128 const ELFFileFormat* FileFormat) const = 0; 129 130 virtual void setRelDynSize() = 0; 131 virtual void setRelPLTSize() = 0; 132 133 void addEhFrameForPLT(Module& pModule); 134 virtual llvm::StringRef createCIERegionForPLT() = 0; 135 virtual llvm::StringRef createFDERegionForPLT() = 0; 136 137protected: 138 Relocator* m_pRelocator; 139 X86PLT* m_pPLT; 140 /// m_RelDyn - dynamic relocation table of .rel.dyn 141 OutputRelocSection* m_pRelDyn; 142 /// m_RelPLT - dynamic relocation table of .rel.plt 143 OutputRelocSection* m_pRelPLT; 144 145 X86ELFDynamic* m_pDynamic; 146 LDSymbol* m_pGOTSymbol; 147 148 size_t m_RelEntrySize; 149 size_t m_RelaEntrySize; 150 151 Relocation::Type m_CopyRel; 152 Relocation::Type m_PointerRel; 153}; 154 155// 156//===----------------------------------------------------------------------===// 157/// X86_32GNULDBackend - linker backend of X86-32 target of GNU ELF format 158/// 159class X86_32GNULDBackend : public X86GNULDBackend 160{ 161public: 162 X86_32GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 163 164 ~X86_32GNULDBackend(); 165 166 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 167 168 X86_32GOT& getGOT(); 169 170 const X86_32GOT& getGOT() const; 171 172 X86_32GOTPLT& getGOTPLT(); 173 174 const X86_32GOTPLT& getGOTPLT() const; 175 176private: 177 /// initRelocator - create and initialize Relocator. 178 bool initRelocator(); 179 180 void setGOTSectionSize(IRBuilder& pBuilder); 181 182 uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 183 184 uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 185 const ELFFileFormat* FileFormat) const; 186 187 void setRelDynSize(); 188 void setRelPLTSize(); 189 190 llvm::StringRef createCIERegionForPLT(); 191 llvm::StringRef createFDERegionForPLT(); 192 193private: 194 X86_32GOT* m_pGOT; 195 X86_32GOTPLT* m_pGOTPLT; 196}; 197 198// 199//===----------------------------------------------------------------------===// 200/// X86_64GNULDBackend - linker backend of X86-64 target of GNU ELF format 201/// 202class X86_64GNULDBackend : public X86GNULDBackend 203{ 204public: 205 X86_64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 206 207 ~X86_64GNULDBackend(); 208 209 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 210 211 X86_64GOT& getGOT(); 212 213 const X86_64GOT& getGOT() const; 214 215 X86_64GOTPLT& getGOTPLT(); 216 217 const X86_64GOTPLT& getGOTPLT() const; 218 219private: 220 /// initRelocator - create and initialize Relocator. 221 bool initRelocator(); 222 223 void setGOTSectionSize(IRBuilder& pBuilder); 224 225 uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 226 227 uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 228 const ELFFileFormat* FileFormat) const; 229 230 void setRelDynSize(); 231 void setRelPLTSize(); 232 233 llvm::StringRef createCIERegionForPLT(); 234 llvm::StringRef createFDERegionForPLT(); 235 236private: 237 X86_64GOT* m_pGOT; 238 X86_64GOTPLT* m_pGOTPLT; 239}; 240} // namespace of mcld 241 242#endif 243 244