X86LDBackend.h revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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 X86GNUInfo; 24 25//===----------------------------------------------------------------------===// 26/// X86GNULDBackend - linker backend of X86 target of GNU ELF format 27/// 28class X86GNULDBackend : public GNULDBackend 29{ 30public: 31 /** \enum ReservedEntryType 32 * \brief The reserved entry type of reserved space in ResolveInfo. 33 * 34 * This is used for sacnRelocation to record what kinds of entries are 35 * reserved for this resolved symbol 36 * 37 * In X86, there are three kinds of entries, GOT, PLT, and dynamic reloction. 38 * GOT may needs a corresponding relocation to relocate itself, so we 39 * separate GOT to two situations: GOT and GOTRel. Besides, for the same 40 * symbol, there might be two kinds of entries reserved for different location. 41 * For example, reference to the same symbol, one may use GOT and the other may 42 * use dynamic relocation. 43 * 44 * bit: 3 2 1 0 45 * | PLT | GOTRel | GOT | Rel | 46 * 47 * value Name - Description 48 * 49 * 0000 None - no reserved entry 50 * 0001 ReserveRel - reserve an dynamic relocation entry 51 * 0010 ReserveGOT - reserve an GOT entry 52 * 0011 GOTandRel - For different relocation, we've reserved GOT and 53 * Rel for different location. 54 * 0100 GOTRel - reserve an GOT entry and the corresponding Dyncamic 55 * relocation entry which relocate this GOT entry 56 * 0101 GOTRelandRel - For different relocation, we've reserved GOTRel 57 * and relocation entry for different location. 58 * 1000 ReservePLT - reserve an PLT entry and the corresponding GOT, 59 * Dynamic relocation entries 60 * 1001 PLTandRel - For different relocation, we've reserved PLT and 61 * Rel for different location. 62 */ 63 enum ReservedEntryType { 64 None = 0, 65 ReserveRel = 1, 66 ReserveGOT = 2, 67 GOTandRel = 3, 68 GOTRel = 4, 69 GOTRelandRel = 5, 70 ReservePLT = 8, 71 PLTandRel = 9 72 }; 73 74public: 75 X86GNULDBackend(const LinkerConfig& pConfig, X86GNUInfo* pInfo); 76 77 ~X86GNULDBackend(); 78 79 uint32_t machine() const; 80 81 X86GOT& getGOT(); 82 83 const X86GOT& getGOT() const; 84 85 X86GOTPLT& getGOTPLT(); 86 87 const X86GOTPLT& getGOTPLT() const; 88 89 X86PLT& getPLT(); 90 91 const X86PLT& getPLT() const; 92 93 X86GOTEntry& getTLSModuleID(); 94 95 /// preLayout - Backend can do any needed modification before layout 96 void doPreLayout(FragmentLinker& pLinker); 97 98 /// postLayout -Backend can do any needed modification after layout 99 void doPostLayout(Module& pModule, FragmentLinker& 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 pSection - the given LDSection 121 /// @param pLayout - for comouting the size of fragment 122 /// @param pRegion - the region to write out data 123 /// @return the size of the table in the file. 124 uint64_t emitSectionData(const LDSection& pSection, 125 MemoryRegion& pRegion) const; 126 127 /// flags - the value of ElfXX_Ehdr::e_flags 128 /// FIXME 129 uint64_t flags() const 130 { return 0x0; } 131 132 uint64_t defaultTextSegmentAddr() const 133 { return 0x08048000; } 134 135 /// initRelocator - create and initialize Relocator. 136 bool initRelocator(const FragmentLinker& pLinker); 137 138 /// getRelocator - return relocator. 139 Relocator* getRelocator(); 140 141 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 142 143 void initTargetSymbols(FragmentLinker& pLinker); 144 145 /// scanRelocation - determine the empty entries are needed or not and create 146 /// the empty entries if needed. 147 /// For X86, following entries are check to create: 148 /// - GOT entry (for .got and .got.plt sections) 149 /// - PLT entry (for .plt section) 150 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 151 void scanRelocation(Relocation& pReloc, 152 FragmentLinker& pLinker, 153 Module& pModule, 154 const LDSection& pSection); 155 156 OutputRelocSection& getRelDyn(); 157 158 const OutputRelocSection& getRelDyn() const; 159 160 OutputRelocSection& getRelPLT(); 161 162 const OutputRelocSection& getRelPLT() const; 163 164 /// getTargetSectionOrder - compute the layout order of X86 target sections 165 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 166 167 /// finalizeTargetSymbols - finalize the symbol value 168 bool finalizeTargetSymbols(FragmentLinker& pLinker); 169 170private: 171 void scanLocalReloc(Relocation& pReloc, 172 FragmentLinker& pLinker, 173 Module& pModule, 174 const LDSection& pSection); 175 176 void scanGlobalReloc(Relocation& pReloc, 177 FragmentLinker& pLinker, 178 Module& pModule, 179 const LDSection& pSection); 180 181 /// addCopyReloc - add a copy relocation into .rel.dyn for pSym 182 /// @param pSym - A resolved copy symbol that defined in BSS section 183 void addCopyReloc(ResolveInfo& pSym); 184 185 /// defineSymbolforCopyReloc - allocate a space in BSS section and 186 /// and force define the copy of pSym to BSS section 187 /// @return the output LDSymbol of the copy symbol 188 LDSymbol& defineSymbolforCopyReloc(FragmentLinker& pLinker, 189 const ResolveInfo& pSym); 190 191 void defineGOTSymbol(FragmentLinker& pLinker); 192 193 /// getRelEntrySize - the size in BYTE of rel type relocation 194 size_t getRelEntrySize() 195 { return 8; } 196 197 /// getRelEntrySize - the size in BYTE of rela type relocation 198 size_t getRelaEntrySize() 199 { return 12; } 200 201 /// doCreateProgramHdrs - backend can implement this function to create the 202 /// target-dependent segments 203 virtual void doCreateProgramHdrs(Module& pModule, 204 const FragmentLinker& pLinker); 205 206private: 207 Relocator* m_pRelocator; 208 X86GOT* m_pGOT; 209 X86PLT* m_pPLT; 210 X86GOTPLT* m_pGOTPLT; 211 /// m_RelDyn - dynamic relocation table of .rel.dyn 212 OutputRelocSection* m_pRelDyn; 213 /// m_RelPLT - dynamic relocation table of .rel.plt 214 OutputRelocSection* m_pRelPLT; 215 216 X86ELFDynamic* m_pDynamic; 217 LDSymbol* m_pGOTSymbol; 218}; 219 220//===----------------------------------------------------------------------===// 221/// X86MachOLDBackend - linker backend of X86 target of MachO format 222/// 223/** 224class X86MachOLDBackend : public DarwinX86LDBackend 225{ 226public: 227 X86MachOLDBackend(); 228 ~X86MachOLDBackend(); 229 230private: 231 MCMachOTargetArchiveReader *createTargetArchiveReader() const; 232 MCMachOTargetObjectReader *createTargetObjectReader() const; 233 MCMachOTargetObjectWriter *createTargetObjectWriter() const; 234 235}; 236**/ 237} // namespace of mcld 238 239#endif 240 241