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 "X86PLT.h" 15 #include <mcld/LD/LDSection.h> 16 #include <mcld/Target/GNULDBackend.h> 17 #include <mcld/Target/OutputRelocSection.h> 18 19 namespace mcld { 20 21 //===----------------------------------------------------------------------===// 22 /// X86GNULDBackend - linker backend of X86 target of GNU ELF format 23 /// 24 class X86GNULDBackend : public GNULDBackend 25 { 26 public: 27 /** \enum ReservedEntryType 28 * \brief The reserved entry type of reserved space in ResolveInfo. 29 * 30 * This is used for sacnRelocation to record what kinds of entries are 31 * reserved for this resolved symbol 32 * 33 * In X86, there are three kinds of entries, GOT, PLT, and dynamic reloction. 34 * GOT may needs a corresponding relocation to relocate itself, so we 35 * separate GOT to two situations: GOT and GOTRel. Besides, for the same 36 * symbol, there might be two kinds of entries reserved for different location. 37 * For example, reference to the same symbol, one may use GOT and the other may 38 * use dynamic relocation. 39 * 40 * bit: 3 2 1 0 41 * | PLT | GOTRel | GOT | Rel | 42 * 43 * value Name - Description 44 * 45 * 0000 None - no reserved entry 46 * 0001 ReserveRel - reserve an dynamic relocation entry 47 * 0010 ReserveGOT - reserve an GOT entry 48 * 0011 GOTandRel - For different relocation, we've reserved GOT and 49 * Rel for different location. 50 * 0100 GOTRel - reserve an GOT entry and the corresponding Dyncamic 51 * relocation entry which relocate this GOT entry 52 * 0101 GOTRelandRel - For different relocation, we've reserved GOTRel 53 * and relocation entry for different location. 54 * 1000 ReservePLT - reserve an PLT entry and the corresponding GOT, 55 * Dynamic relocation entries 56 * 1001 PLTandRel - For different relocation, we've reserved PLT and 57 * Rel for different location. 58 */ 59 enum ReservedEntryType { 60 None = 0, 61 ReserveRel = 1, 62 ReserveGOT = 2, 63 GOTandRel = 3, 64 GOTRel = 4, 65 GOTRelandRel = 5, 66 ReservePLT = 8, 67 PLTandRel = 9 68 }; 69 70 X86GNULDBackend(); 71 72 ~X86GNULDBackend(); 73 74 RelocationFactory* getRelocFactory(); 75 76 uint32_t machine() const; 77 78 bool isLittleEndian() const 79 { return true; } 80 81 X86GOT& getGOT(); 82 83 const X86GOT& getGOT() const; 84 85 X86PLT& getPLT(); 86 87 const X86PLT& getPLT() const; 88 89 unsigned int bitclass() const; 90 91 /// preLayout - Backend can do any needed modification before layout 92 void doPreLayout(const Output& pOutput, 93 const MCLDInfo& pInfo, 94 MCLinker& pLinker); 95 96 /// postLayout -Backend can do any needed modification after layout 97 void doPostLayout(const Output& pOutput, 98 const MCLDInfo& pInfo, 99 MCLinker& pLinker); 100 101 /// dynamic - the dynamic section of the target machine. 102 /// Use co-variant return type to return its own dynamic section. 103 X86ELFDynamic& dynamic(); 104 105 /// dynamic - the dynamic section of the target machine. 106 /// Use co-variant return type to return its own dynamic section. 107 const X86ELFDynamic& dynamic() const; 108 109 /// emitSectionData - write out the section data into the memory region. 110 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 111 /// call back target backend to emit the data. 112 /// 113 /// Backends handle the target-special tables (plt, gp,...) by themselves. 114 /// Backend can put the data of the tables in MCSectionData directly 115 /// - LDSection.getSectionData can get the section data. 116 /// Or, backend can put the data into special data structure 117 /// - backend can maintain its own map<LDSection, table> to get the table 118 /// from given LDSection. 119 /// 120 /// @param pOutput - the output file 121 /// @param pSection - the given LDSection 122 /// @param pInfo - all options in the command line. 123 /// @param pRegion - the region to write out data 124 /// @return the size of the table in the file. 125 uint64_t emitSectionData(const Output& pOutput, 126 const LDSection& pSection, 127 const MCLDInfo& pInfo, 128 MemoryRegion& pRegion) const; 129 130 /// OSABI - the value of e_ident[EI_OSABI] 131 /// FIXME 132 uint8_t OSABI() const 133 { return llvm::ELF::ELFOSABI_NONE; } 134 135 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 136 /// FIXME 137 uint8_t ABIVersion() const 138 { return 0x0; } 139 140 /// flags - the value of ElfXX_Ehdr::e_flags 141 /// FIXME 142 uint64_t flags() const 143 { return 0x0; } 144 145 /// initTargetSectionMap - initialize target dependent section mapping 146 bool initTargetSectionMap(SectionMap& pSectionMap); 147 148 // initRelocFactory - create and initialize RelocationFactory 149 bool initRelocFactory(const MCLinker& pLinker); 150 151 void initTargetSections(MCLinker& pLinker); 152 153 void initTargetSymbols(MCLinker& pLinker); 154 155 /// scanRelocation - determine the empty entries are needed or not and create 156 /// the empty entries if needed. 157 /// For X86, following entries are check to create: 158 /// - GOT entry (for .got and .got.plt sections) 159 /// - PLT entry (for .plt section) 160 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 161 void scanRelocation(Relocation& pReloc, 162 const LDSymbol& pInputSym, 163 MCLinker& pLinker, 164 const MCLDInfo& pLDInfo, 165 const Output& pOutput); 166 167 OutputRelocSection& getRelDyn(); 168 169 const OutputRelocSection& getRelDyn() const; 170 171 OutputRelocSection& getRelPLT(); 172 173 const OutputRelocSection& getRelPLT() const; 174 175 /// getTargetSectionOrder - compute the layout order of X86 target sections 176 unsigned int getTargetSectionOrder(const Output& pOutput, 177 const LDSection& pSectHdr) const; 178 179 /// finalizeSymbol - finalize the symbol value 180 /// If the symbol's reserved field is not zero, MCLinker will call back this 181 /// function to ask the final value of the symbol 182 bool finalizeSymbol(LDSymbol& pSymbol) const; 183 184 /// allocateCommonSymbols - allocate common symbols in the corresponding 185 /// sections. 186 bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const; 187 188 public: 189 bool isSymbolPreemptible(const ResolveInfo& pSym, 190 const MCLDInfo& pLDInfo, 191 const Output& pOutput) const; 192 193 private: 194 void scanLocalReloc(Relocation& pReloc, 195 const LDSymbol& pInputSym, 196 MCLinker& pLinker, 197 const MCLDInfo& pLDInfo, 198 const Output& pOutput); 199 200 void scanGlobalReloc(Relocation& pReloc, 201 const LDSymbol& pInputSym, 202 MCLinker& pLinker, 203 const MCLDInfo& pLDInfo, 204 const Output& pOutput); 205 206 bool isSymbolNeedsPLT(const ResolveInfo& pSym, 207 const MCLDInfo& pLDInfo, 208 const Output& pOutput) const; 209 210 bool isSymbolNeedsDynRel(const ResolveInfo& pSym, 211 const Output& pOutput, 212 bool isAbsReloc) const; 213 214 void updateAddend(Relocation& pReloc, 215 const LDSymbol& pInputSym, 216 const Layout& pLayout) const; 217 218 void createX86GOT(MCLinker& pLinker, const Output& pOutput); 219 void createX86PLTandRelPLT(MCLinker& pLinker, const Output& pOutput); 220 void createX86RelDyn(MCLinker& pLinker, const Output& pOutput); 221 222 ELFFileFormat* getOutputFormat(const Output& pOutput) const; 223 224 private: 225 RelocationFactory* m_pRelocFactory; 226 X86GOT* m_pGOT; 227 X86PLT* m_pPLT; 228 /// m_RelDyn - dynamic relocation table of .rel.dyn 229 OutputRelocSection* m_pRelDyn; 230 /// m_RelPLT - dynamic relocation table of .rel.plt 231 OutputRelocSection* m_pRelPLT; 232 233 X86ELFDynamic* m_pDynamic; 234 LDSymbol* m_pGOTSymbol; 235 }; 236 237 //===----------------------------------------------------------------------===// 238 /// X86MachOLDBackend - linker backend of X86 target of MachO format 239 /// 240 /** 241 class X86MachOLDBackend : public DarwinX86LDBackend 242 { 243 public: 244 X86MachOLDBackend(); 245 ~X86MachOLDBackend(); 246 247 private: 248 MCMachOTargetArchiveReader *createTargetArchiveReader() const; 249 MCMachOTargetObjectReader *createTargetObjectReader() const; 250 MCMachOTargetObjectWriter *createTargetObjectWriter() const; 251 252 }; 253 **/ 254 } // namespace of mcld 255 256 #endif 257