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 MCLinker; 18 class OutputRelocSection; 19 class SectionMap; 20 21 //===----------------------------------------------------------------------===// 22 /// MipsGNULDBackend - linker backend of Mips target of GNU ELF format 23 /// 24 class MipsGNULDBackend : public GNULDBackend 25 { 26 public: 27 enum ReservedEntryType { 28 None = 0, // no reserved entry 29 ReserveRel = 1, // reserve a dynamic relocation entry 30 ReserveGot = 2, // reserve a GOT entry 31 ReserveGpDisp = 8 // reserve _gp_disp symbol 32 }; 33 34 public: 35 MipsGNULDBackend(); 36 ~MipsGNULDBackend(); 37 38 public: 39 /// initTargetSectionMap - initialize target dependent section mapping. 40 bool initTargetSectionMap(SectionMap& pSectionMap); 41 42 /// initTargetSections - initialize target dependent sections in output 43 void initTargetSections(MCLinker& pLinker); 44 45 /// initTargetSymbols - initialize target dependent symbols in output. 46 void initTargetSymbols(MCLinker& pLinker); 47 48 /// initRelocFactory - create and initialize RelocationFactory. 49 bool initRelocFactory(const MCLinker& pLinker); 50 51 /// getRelocFactory - return relocation factory. 52 RelocationFactory* getRelocFactory(); 53 54 /// scanRelocation - determine the empty entries are needed or not and 55 /// create the empty entries if needed. 56 /// For Mips, the GOT, GP, and dynamic relocation entries are check to create. 57 void scanRelocation(Relocation& pReloc, 58 const LDSymbol& pInputSym, 59 MCLinker& pLinker, 60 const MCLDInfo& pLDInfo, 61 const Output& pOutput); 62 63 uint32_t machine() const; 64 65 /// OSABI - the value of e_ident[EI_OSABI] 66 uint8_t OSABI() const; 67 68 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 69 uint8_t ABIVersion() const; 70 71 /// flags - the value of ElfXX_Ehdr::e_flags 72 uint64_t flags() const; 73 74 bool isLittleEndian() const; 75 76 unsigned int bitclass() const; 77 78 /// preLayout - Backend can do any needed modification before layout 79 void doPreLayout(const Output& pOutput, 80 const MCLDInfo& pInfo, 81 MCLinker& pLinker); 82 83 /// postLayout -Backend can do any needed modification after layout 84 void doPostLayout(const Output& pOutput, 85 const MCLDInfo& pInfo, 86 MCLinker& pLinker); 87 88 /// dynamic - the dynamic section of the target machine. 89 /// Use co-variant return type to return its own dynamic section. 90 MipsELFDynamic& dynamic(); 91 92 /// dynamic - the dynamic section of the target machine. 93 /// Use co-variant return type to return its own dynamic section. 94 const MipsELFDynamic& dynamic() const; 95 96 /// emitSectionData - write out the section data into the memory region. 97 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 98 /// call back target backend to emit the data. 99 /// 100 /// Backends handle the target-special tables (plt, gp,...) by themselves. 101 /// Backend can put the data of the tables in MCSectionData directly 102 /// - LDSection.getSectionData can get the section data. 103 /// Or, backend can put the data into special data structure 104 /// - backend can maintain its own map<LDSection, table> to get the table 105 /// from given LDSection. 106 /// 107 /// @param pOutput - the output file 108 /// @param pSection - the given LDSection 109 /// @param pInfo - all options in the command line. 110 /// @param pRegion - the region to write out data 111 /// @return the size of the table in the file. 112 uint64_t emitSectionData(const Output& pOutput, 113 const LDSection& pSection, 114 const MCLDInfo& pInfo, 115 MemoryRegion& pRegion) const; 116 117 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 118 virtual void emitDynNamePools(Output& pOutput, 119 SymbolCategory& pSymbols, 120 const Layout& pLayout, 121 const MCLDInfo& pLDInfo); 122 123 MipsGOT& getGOT(); 124 const MipsGOT& getGOT() const; 125 126 OutputRelocSection& getRelDyn(); 127 const OutputRelocSection& getRelDyn() const; 128 129 /// getTargetSectionOrder - compute the layout order of ARM target sections 130 unsigned int getTargetSectionOrder(const Output& pOutput, 131 const LDSection& pSectHdr) const; 132 133 /// finalizeSymbol - finalize the symbol value 134 /// If the symbol's reserved field is not zero, MCLinker will call back this 135 /// function to ask the final value of the symbol 136 bool finalizeSymbol(LDSymbol& pSymbol) const; 137 138 /// allocateCommonSymbols - allocate common symbols in the corresponding 139 /// sections. 140 bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const; 141 142 private: 143 void scanLocalReloc(Relocation& pReloc, 144 const LDSymbol& pInputSym, 145 MCLinker& pLinker, 146 const MCLDInfo& pLDInfo, 147 const Output& pOutput); 148 149 void scanGlobalReloc(Relocation& pReloc, 150 const LDSymbol& pInputSym, 151 MCLinker& pLinker, 152 const MCLDInfo& pLDInfo, 153 const Output& pOutput); 154 155 bool isSymbolNeedsPLT(ResolveInfo& pSym, const Output& pOutput) const; 156 bool isSymbolNeedsDynRel(ResolveInfo& pSym, const Output& pOutput) const; 157 158 void createGOT(MCLinker& pLinker, const Output& pOutput); 159 void createRelDyn(MCLinker& pLinker, const Output& pOutput); 160 161 ELFFileFormat* getOutputFormat(const Output& pOutput) const; 162 163 /// updateAddend - update addend value of the relocation if the 164 /// the target symbol is a section symbol. Addend is the offset 165 /// in the section. This value should be updated after section 166 /// merged. 167 void updateAddend(Relocation& pReloc, 168 const LDSymbol& pInputSym, 169 const Layout& pLayout) const; 170 171 private: 172 RelocationFactory* m_pRelocFactory; 173 174 MipsGOT* m_pGOT; // .got 175 OutputRelocSection* m_pRelDyn; // .rel.dyn 176 177 MipsELFDynamic* m_pDynamic; 178 LDSymbol* m_pGOTSymbol; 179 LDSymbol* m_pGpDispSymbol; 180 181 std::vector<LDSymbol*> m_LocalGOTSyms; 182 std::vector<LDSymbol*> m_GlobalGOTSyms; 183 184 private: 185 /// isGOTSymbol - return true if the symbol is the GOT entry. 186 bool isGOTSymbol(const LDSymbol& pSymbol) const; 187 /// emitDynamicSymbol - emit dynamic symbol. 188 void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 189 Output& pOutput, 190 LDSymbol& pSymbol, 191 const Layout& pLayout, 192 char* strtab, 193 size_t strtabsize, 194 size_t symtabIdx); 195 }; 196 197 } // namespace of mcld 198 199 #endif 200