MipsLDBackend.h revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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#include "MipsGOTPLT.h" 15#include "MipsPLT.h" 16 17namespace mcld { 18 19class LinkerConfig; 20class OutputRelocSection; 21class SectionMap; 22class MemoryArea; 23class MipsGNUInfo; 24 25/** \class MipsGNULDBackend 26 * \brief Base linker backend of Mips target of GNU ELF format. 27 */ 28class MipsGNULDBackend : public GNULDBackend 29{ 30public: 31 typedef std::vector<LDSymbol*> SymbolListType; 32 33public: 34 MipsGNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 35 ~MipsGNULDBackend(); 36 37 bool needsLA25Stub(Relocation::Type pType, const mcld::ResolveInfo* pSym); 38 39 void addNonPICBranchSym(ResolveInfo* rsym); 40 bool hasNonPICBranch(const ResolveInfo* rsym) const; 41 42public: 43 /// initTargetSections - initialize target dependent sections in output 44 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 45 46 /// initTargetSymbols - initialize target dependent symbols in output. 47 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 48 49 /// getRelocator - return relocator. 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 130private: 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 211private: 212 typedef llvm::DenseSet<const ResolveInfo*> ResolveInfoSetType; 213 typedef llvm::DenseMap<const Input*, llvm::ELF::Elf64_Addr> GP0MapType; 214 215protected: 216 Relocator* m_pRelocator; 217 MipsGOT* m_pGOT; // .got 218 MipsPLT* m_pPLT; // .plt 219 MipsGOTPLT* m_pGOTPLT; // .got.plt 220 221private: 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{ 242public: 243 Mips32GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 244 245private: 246 // MipsGNULDBackend 247 248 bool initRelocator(); 249 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 250 size_t getRelEntrySize(); 251 size_t getRelaEntrySize(); 252}; 253 254/** \class Mips64GNULDBackend 255 * \brief Base linker backend of Mips 64-bit target of GNU ELF format. 256 */ 257class Mips64GNULDBackend : public MipsGNULDBackend 258{ 259public: 260 Mips64GNULDBackend(const LinkerConfig& pConfig, MipsGNUInfo* pInfo); 261 262private: 263 // MipsGNULDBackend 264 265 bool initRelocator(); 266 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 267 size_t getRelEntrySize(); 268 size_t getRelaEntrySize(); 269}; 270 271} // namespace of mcld 272 273#endif 274