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