1 //===- MipsLDBackend.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 MIPS_LDBACKEND_H 10 #define MIPS_LDBACKEND_H 11 #include <mcld/Target/GNULDBackend.h> 12 #include "MipsELFDynamic.h" 13 #include "MipsGOT.h" 14 15 namespace mcld { 16 17 class LinkerConfig; 18 class OutputRelocSection; 19 class SectionMap; 20 class MemoryArea; 21 class MipsGNUInfo; 22 23 //===----------------------------------------------------------------------===// 24 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format 25 /// 26 class MipsGNULDBackend : public GNULDBackend 27 { 28 public: 29 enum ReservedEntryType { 30 None = 0, // no reserved entry 31 ReserveRel = 1, // reserve a dynamic relocation entry 32 ReserveGot = 2, // reserve a GOT entry 33 ReserveGpDisp = 8 // reserve _gp_disp symbol 34 }; 35 36 public: 37 MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 38 ~MipsGNULDBackend(); 39 40 public: 41 /// initTargetSections - initialize target dependent sections in output 42 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 43 44 /// initTargetSymbols - initialize target dependent symbols in output. 45 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 46 47 /// initRelocator - create and initialize Relocator. 48 bool initRelocator(); 49 50 /// getRelocator - return relocator. 51 Relocator* getRelocator(); 52 53 /// scanRelocation - determine the empty entries are needed or not and 54 /// create the empty entries if needed. 55 /// For Mips, the GOT, GP, and dynamic relocation entries are check to create. 56 void scanRelocation(Relocation& pReloc, 57 IRBuilder& pBuilder, 58 Module& pModule, 59 LDSection& pSection); 60 61 /// preLayout - Backend can do any needed modification before layout 62 void doPreLayout(IRBuilder& pBuilder); 63 64 /// postLayout - Backend can do any needed modification after layout 65 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 66 67 /// dynamic - the dynamic section of the target machine. 68 /// Use co-variant return type to return its own dynamic section. 69 MipsELFDynamic& dynamic(); 70 71 /// dynamic - the dynamic section of the target machine. 72 /// Use co-variant return type to return its own dynamic section. 73 const MipsELFDynamic& dynamic() const; 74 75 /// emitSectionData - write out the section data into the memory region. 76 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 77 /// call back target backend to emit the data. 78 /// 79 /// Backends handle the target-special tables (plt, gp,...) by themselves. 80 /// Backend can put the data of the tables in SectionData directly 81 /// - LDSection.getSectionData can get the section data. 82 /// Or, backend can put the data into special data structure 83 /// - backend can maintain its own map<LDSection, table> to get the table 84 /// from given LDSection. 85 /// 86 /// @param pSection - the given LDSection 87 /// @param pRegion - the region to write out data 88 /// @return the size of the table in the file. 89 uint64_t emitSectionData(const LDSection& pSection, 90 MemoryRegion& pRegion) const; 91 92 void sizeNamePools(Module& pModule, bool pIsStaticLink); 93 94 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 95 void emitDynNamePools(Module& pModule, MemoryArea& pOut); 96 97 98 MipsGOT& getGOT(); 99 const MipsGOT& getGOT() const; 100 101 OutputRelocSection& getRelDyn(); 102 const OutputRelocSection& getRelDyn() const; 103 104 /// getTargetSectionOrder - compute the layout order of ARM target sections 105 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 106 107 /// finalizeSymbol - finalize the symbol value 108 bool finalizeTargetSymbols(); 109 110 /// allocateCommonSymbols - allocate common symbols in the corresponding 111 /// sections. 112 bool allocateCommonSymbols(Module& pModule); 113 114 private: 115 void scanLocalReloc(Relocation& pReloc, 116 IRBuilder& pBuilder, 117 const LDSection& pSection); 118 119 void scanGlobalReloc(Relocation& pReloc, 120 IRBuilder& pBuilder, 121 const LDSection& pSection); 122 123 void defineGOTSymbol(IRBuilder& pBuilder); 124 125 /// emitSymbol32 - emit an ELF32 symbol, override parent's function 126 void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32, 127 LDSymbol& pSymbol, 128 char* pStrtab, 129 size_t pStrtabsize, 130 size_t pSymtabIdx); 131 132 /// getRelEntrySize - the size in BYTE of rel type relocation 133 size_t getRelEntrySize() 134 { return 8; } 135 136 /// getRelEntrySize - the size in BYTE of rela type relocation 137 size_t getRelaEntrySize() 138 { return 12; } 139 140 /// doCreateProgramHdrs - backend can implement this function to create the 141 /// target-dependent segments 142 void doCreateProgramHdrs(Module& pModule); 143 144 private: 145 Relocator* m_pRelocator; 146 147 MipsGOT* m_pGOT; // .got 148 OutputRelocSection* m_pRelDyn; // .rel.dyn 149 150 MipsELFDynamic* m_pDynamic; 151 LDSymbol* m_pGOTSymbol; 152 LDSymbol* m_pGpDispSymbol; 153 154 std::vector<LDSymbol*> m_GlobalGOTSyms; 155 156 private: 157 /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 158 bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const; 159 160 }; 161 162 } // namespace of mcld 163 164 #endif 165 166