MipsLDBackend.h revision 37b74a387bb3993387029859c2d9d051c41c724e
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 TARGET_MIPS_MIPSLDBACKEND_H_ 10#define TARGET_MIPS_MIPSLDBACKEND_H_ 11#include "mcld/Target/GNULDBackend.h" 12#include "MipsELFDynamic.h" 13#include "MipsGOT.h" 14#include "MipsGOTPLT.h" 15#include "MipsPLT.h" 16 17namespace mcld { 18 19class LinkerConfig; 20class MemoryArea; 21class MipsGNUInfo; 22class OutputRelocSection; 23class SectionMap; 24 25/** \class MipsGNULDBackend 26 * \brief Base linker backend of Mips target of GNU ELF format. 27 */ 28class MipsGNULDBackend : public GNULDBackend { 29 public: 30 typedef std::vector<LDSymbol*> SymbolListType; 31 32 public: 33 MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 34 ~MipsGNULDBackend(); 35 36 bool needsLA25Stub(Relocation::Type pType, const mcld::ResolveInfo* pSym); 37 38 void addNonPICBranchSym(ResolveInfo* rsym); 39 bool hasNonPICBranch(const ResolveInfo* rsym) const; 40 41 public: 42 /// initTargetSections - initialize target dependent sections in output 43 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 44 45 /// initTargetSymbols - initialize target dependent symbols in output. 46 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 47 48 /// getRelocator - return relocator. 49 const Relocator* getRelocator() const; 50 Relocator* getRelocator(); 51 52 /// preLayout - Backend can do any needed modification before layout 53 void doPreLayout(IRBuilder& pBuilder); 54 55 /// postLayout - Backend can do any needed modification after layout 56 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 57 58 /// dynamic - the dynamic section of the target machine. 59 /// Use co-variant return type to return its own dynamic section. 60 MipsELFDynamic& dynamic(); 61 62 /// dynamic - the dynamic section of the target machine. 63 /// Use co-variant return type to return its own dynamic section. 64 const MipsELFDynamic& dynamic() const; 65 66 /// emitSectionData - write out the section data into the memory region. 67 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 68 /// call back target backend to emit the data. 69 /// 70 /// Backends handle the target-special tables (plt, gp,...) by themselves. 71 /// Backend can put the data of the tables in SectionData directly 72 /// - LDSection.getSectionData can get the section data. 73 /// Or, backend can put the data into special data structure 74 /// - backend can maintain its own map<LDSection, table> to get the table 75 /// from given LDSection. 76 /// 77 /// @param pSection - the given LDSection 78 /// @param pRegion - the region to write out data 79 /// @return the size of the table in the file. 80 uint64_t emitSectionData(const LDSection& pSection, 81 MemoryRegion& pRegion) const; 82 83 /// hasEntryInStrTab - symbol has an entry in a .strtab 84 bool hasEntryInStrTab(const LDSymbol& pSym) const; 85 86 /// orderSymbolTable - order symbol table before emitting 87 void orderSymbolTable(Module& pModule); 88 89 /// readSection - read a target dependent section. 90 bool readSection(Input& pInput, SectionData& pSD); 91 92 MipsGOT& getGOT(); 93 const MipsGOT& getGOT() const; 94 95 MipsPLT& getPLT(); 96 const MipsPLT& getPLT() const; 97 98 MipsGOTPLT& getGOTPLT(); 99 const MipsGOTPLT& getGOTPLT() const; 100 101 OutputRelocSection& getRelPLT(); 102 const OutputRelocSection& getRelPLT() const; 103 104 OutputRelocSection& getRelDyn(); 105 const OutputRelocSection& getRelDyn() const; 106 107 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 108 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 109 110 LDSymbol* getGpDispSymbol() { return m_pGpDispSymbol; } 111 const LDSymbol* getGpDispSymbol() const { return m_pGpDispSymbol; } 112 113 SymbolListType& getGlobalGOTSyms() { return m_GlobalGOTSyms; } 114 const SymbolListType& getGlobalGOTSyms() const { return m_GlobalGOTSyms; } 115 116 /// getTargetSectionOrder - compute the layout order of ARM target sections 117 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 118 119 /// finalizeSymbol - finalize the symbol value 120 bool finalizeTargetSymbols(); 121 122 /// allocateCommonSymbols - allocate common symbols in the corresponding 123 /// sections. 124 bool allocateCommonSymbols(Module& pModule); 125 126 /// getGP0 - the gp value used to create the relocatable objects 127 /// in the specified input. 128 uint64_t getGP0(const Input& pInput) const; 129 130 private: 131 void defineGOTSymbol(IRBuilder& pBuilder); 132 void defineGOTPLTSymbol(IRBuilder& pBuilder); 133 134 bool relaxRelocation(IRBuilder& pBuilder, Relocation& pRel); 135 136 /// emitSymbol32 - emit an ELF32 symbol, override parent's function 137 void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32, 138 LDSymbol& pSymbol, 139 char* pStrtab, 140 size_t pStrtabsize, 141 size_t pSymtabIdx); 142 143 /// doCreateProgramHdrs - backend can implement this function to create the 144 /// target-dependent segments 145 void doCreateProgramHdrs(Module& pModule); 146 147 /// mayRelax - Backends should override this function if they need relaxation 148 bool mayRelax() { return true; } 149 150 /// doRelax - Backend can orevride this function to add its relaxation 151 /// implementation. Return true if the output (e.g., .text) is "relaxed" 152 /// (i.e. layout is changed), and set pFinished to true if everything is fit, 153 /// otherwise set it to false. 154 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 155 156 /// initTargetStubs 157 bool initTargetStubs(); 158 159 /// readRelocation - read ELF32_Rel entry 160 bool readRelocation(const llvm::ELF::Elf32_Rel& pRel, 161 Relocation::Type& pType, 162 uint32_t& pSymIdx, 163 uint32_t& pOffset) const; 164 165 /// readRelocation - read ELF32_Rela entry 166 bool readRelocation(const llvm::ELF::Elf32_Rela& pRel, 167 Relocation::Type& pType, 168 uint32_t& pSymIdx, 169 uint32_t& pOffset, 170 int32_t& pAddend) const; 171 172 /// readRelocation - read ELF64_Rel entry 173 bool readRelocation(const llvm::ELF::Elf64_Rel& pRel, 174 Relocation::Type& pType, 175 uint32_t& pSymIdx, 176 uint64_t& pOffset) const; 177 178 /// readRel - read ELF64_Rela entry 179 bool readRelocation(const llvm::ELF::Elf64_Rela& pRel, 180 Relocation::Type& pType, 181 uint32_t& pSymIdx, 182 uint64_t& pOffset, 183 int64_t& pAddend) const; 184 185 /// emitRelocation - write data to the ELF32_Rel entry 186 void emitRelocation(llvm::ELF::Elf32_Rel& pRel, 187 Relocation::Type pType, 188 uint32_t pSymIdx, 189 uint32_t pOffset) const; 190 191 /// emitRelocation - write data to the ELF32_Rela entry 192 void emitRelocation(llvm::ELF::Elf32_Rela& pRel, 193 Relocation::Type pType, 194 uint32_t pSymIdx, 195 uint32_t pOffset, 196 int32_t pAddend) const; 197 198 /// emitRelocation - write data to the ELF64_Rel entry 199 void emitRelocation(llvm::ELF::Elf64_Rel& pRel, 200 Relocation::Type pType, 201 uint32_t pSymIdx, 202 uint64_t pOffset) const; 203 204 /// emitRelocation - write data to the ELF64_Rela entry 205 void emitRelocation(llvm::ELF::Elf64_Rela& pRel, 206 Relocation::Type pType, 207 uint32_t pSymIdx, 208 uint64_t pOffset, 209 int64_t pAddend) const; 210 211 private: 212 typedef llvm::DenseSet<const ResolveInfo*> ResolveInfoSetType; 213 typedef llvm::DenseMap<const Input*, llvm::ELF::Elf64_Addr> GP0MapType; 214 215 protected: 216 Relocator* m_pRelocator; 217 MipsGOT* m_pGOT; // .got 218 MipsPLT* m_pPLT; // .plt 219 MipsGOTPLT* m_pGOTPLT; // .got.plt 220 221 private: 222 MipsGNUInfo& m_pInfo; 223 224 OutputRelocSection* m_pRelPlt; // .rel.plt 225 OutputRelocSection* m_pRelDyn; // .rel.dyn 226 227 MipsELFDynamic* m_pDynamic; 228 LDSymbol* m_pGOTSymbol; 229 LDSymbol* m_pPLTSymbol; 230 LDSymbol* m_pGpDispSymbol; 231 232 SymbolListType m_GlobalGOTSyms; 233 ResolveInfoSetType m_HasNonPICBranchSyms; 234 GP0MapType m_GP0Map; 235}; 236 237/** \class Mips32GNULDBackend 238 * \brief Base linker backend of Mips 32-bit target of GNU ELF format. 239 */ 240class Mips32GNULDBackend : public MipsGNULDBackend { 241 public: 242 Mips32GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 243 244 private: 245 // MipsGNULDBackend 246 247 bool initRelocator(); 248 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 249 size_t getRelEntrySize(); 250 size_t getRelaEntrySize(); 251}; 252 253/** \class Mips64GNULDBackend 254 * \brief Base linker backend of Mips 64-bit target of GNU ELF format. 255 */ 256class Mips64GNULDBackend : public MipsGNULDBackend { 257 public: 258 Mips64GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 259 260 private: 261 // MipsGNULDBackend 262 263 bool initRelocator(); 264 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 265 size_t getRelEntrySize(); 266 size_t getRelaEntrySize(); 267}; 268 269} // namespace mcld 270 271#endif // TARGET_MIPS_MIPSLDBACKEND_H_ 272