MipsLDBackend.h revision cedee4b38f4786845183be7f5916dd520a170ae0
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 15namespace mcld { 16 17class MCLinker; 18class OutputRelocSection; 19class SectionMap; 20 21//===----------------------------------------------------------------------===// 22/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format 23/// 24class MipsGNULDBackend : public GNULDBackend 25{ 26public: 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 34public: 35 MipsGNULDBackend(); 36 ~MipsGNULDBackend(); 37 38public: 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, const Output& pOutput); 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 const LDSection& pSection); 63 64 uint32_t machine() const; 65 66 /// OSABI - the value of e_ident[EI_OSABI] 67 uint8_t OSABI() const; 68 69 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 70 uint8_t ABIVersion() const; 71 72 /// flags - the value of ElfXX_Ehdr::e_flags 73 uint64_t flags() const; 74 75 bool isLittleEndian() const; 76 77 unsigned int bitclass() const; 78 79 uint64_t defaultTextSegmentAddr() const; 80 81 /// abiPageSize - the abi page size of the target machine 82 uint64_t abiPageSize(const MCLDInfo& pInfo) const; 83 84 /// preLayout - Backend can do any needed modification before layout 85 void doPreLayout(const Output& pOutput, 86 const MCLDInfo& pInfo, 87 MCLinker& pLinker); 88 89 /// postLayout -Backend can do any needed modification after layout 90 void doPostLayout(const Output& pOutput, 91 const MCLDInfo& pInfo, 92 MCLinker& pLinker); 93 94 /// dynamic - the dynamic section of the target machine. 95 /// Use co-variant return type to return its own dynamic section. 96 MipsELFDynamic& dynamic(); 97 98 /// dynamic - the dynamic section of the target machine. 99 /// Use co-variant return type to return its own dynamic section. 100 const MipsELFDynamic& dynamic() const; 101 102 /// emitSectionData - write out the section data into the memory region. 103 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 104 /// call back target backend to emit the data. 105 /// 106 /// Backends handle the target-special tables (plt, gp,...) by themselves. 107 /// Backend can put the data of the tables in SectionData directly 108 /// - LDSection.getSectionData can get the section data. 109 /// Or, backend can put the data into special data structure 110 /// - backend can maintain its own map<LDSection, table> to get the table 111 /// from given LDSection. 112 /// 113 /// @param pOutput - the output file 114 /// @param pSection - the given LDSection 115 /// @param pInfo - all options in the command line. 116 /// @param pLayout - for comouting the size of fragment 117 /// @param pRegion - the region to write out data 118 /// @return the size of the table in the file. 119 uint64_t emitSectionData(const Output& pOutput, 120 const LDSection& pSection, 121 const MCLDInfo& pInfo, 122 const Layout& pLayout, 123 MemoryRegion& pRegion) const; 124 125 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 126 virtual void emitDynNamePools(Output& pOutput, 127 SymbolCategory& pSymbols, 128 const Layout& pLayout, 129 const MCLDInfo& pLDInfo); 130 131 MipsGOT& getGOT(); 132 const MipsGOT& getGOT() const; 133 134 OutputRelocSection& getRelDyn(); 135 const OutputRelocSection& getRelDyn() const; 136 137 /// getTargetSectionOrder - compute the layout order of ARM target sections 138 unsigned int getTargetSectionOrder(const Output& pOutput, 139 const LDSection& pSectHdr, 140 const MCLDInfo& pInfo) const; 141 142 /// finalizeSymbol - finalize the symbol value 143 bool finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput); 144 145 /// allocateCommonSymbols - allocate common symbols in the corresponding 146 /// sections. 147 bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const; 148 149private: 150 void scanLocalReloc(Relocation& pReloc, 151 const LDSymbol& pInputSym, 152 MCLinker& pLinker, 153 const MCLDInfo& pLDInfo, 154 const Output& pOutput); 155 156 void scanGlobalReloc(Relocation& pReloc, 157 const LDSymbol& pInputSym, 158 MCLinker& pLinker, 159 const MCLDInfo& pLDInfo, 160 const Output& pOutput); 161 162 void createGOT(MCLinker& pLinker, const Output& pOutput); 163 void createRelDyn(MCLinker& pLinker, const Output& pOutput); 164 165 /// updateAddend - update addend value of the relocation if the 166 /// the target symbol is a section symbol. Addend is the offset 167 /// in the section. This value should be updated after section 168 /// merged. 169 void updateAddend(Relocation& pReloc, 170 const LDSymbol& pInputSym, 171 const Layout& pLayout) const; 172 173private: 174 RelocationFactory* m_pRelocFactory; 175 176 MipsGOT* m_pGOT; // .got 177 OutputRelocSection* m_pRelDyn; // .rel.dyn 178 179 MipsELFDynamic* m_pDynamic; 180 LDSymbol* m_pGOTSymbol; 181 LDSymbol* m_pGpDispSymbol; 182 183 std::vector<LDSymbol*> m_GlobalGOTSyms; 184 185private: 186 /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 187 bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const; 188 /// emitDynamicSymbol - emit dynamic symbol. 189 void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32, 190 Output& pOutput, 191 LDSymbol& pSymbol, 192 const Layout& pLayout, 193 char* strtab, 194 size_t strtabsize, 195 size_t symtabIdx); 196}; 197 198} // namespace of mcld 199 200#endif 201 202