MipsLDBackend.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 LinkerConfig; 18class FragmentLinker; 19class OutputRelocSection; 20class SectionMap; 21class MemoryArea; 22 23//===----------------------------------------------------------------------===// 24/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format 25/// 26class MipsGNULDBackend : public GNULDBackend 27{ 28public: 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 36public: 37 MipsGNULDBackend(const LinkerConfig& pConfig); 38 ~MipsGNULDBackend(); 39 40public: 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(FragmentLinker& pLinker); 46 47 /// initRelocFactory - create and initialize RelocationFactory. 48 bool initRelocFactory(const FragmentLinker& pLinker); 49 50 /// getRelocFactory - return relocation factory. 51 RelocationFactory* getRelocFactory(); 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 FragmentLinker& pLinker, 58 Module& pModule, 59 const LDSection& pSection); 60 61 uint32_t machine() const; 62 63 /// OSABI - the value of e_ident[EI_OSABI] 64 uint8_t OSABI() const; 65 66 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 67 uint8_t ABIVersion() const; 68 69 /// flags - the value of ElfXX_Ehdr::e_flags 70 uint64_t flags() const; 71 72 bool isLittleEndian() const; 73 74 unsigned int bitclass() const; 75 76 uint64_t defaultTextSegmentAddr() const; 77 78 /// abiPageSize - the abi page size of the target machine 79 uint64_t abiPageSize() const; 80 81 /// preLayout - Backend can do any needed modification before layout 82 void doPreLayout(FragmentLinker& pLinker); 83 84 /// postLayout -Backend can do any needed modification after layout 85 void doPostLayout(Module& pModule, FragmentLinker& pLinker); 86 87 /// dynamic - the dynamic section of the target machine. 88 /// Use co-variant return type to return its own dynamic section. 89 MipsELFDynamic& dynamic(); 90 91 /// dynamic - the dynamic section of the target machine. 92 /// Use co-variant return type to return its own dynamic section. 93 const MipsELFDynamic& dynamic() const; 94 95 /// emitSectionData - write out the section data into the memory region. 96 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 97 /// call back target backend to emit the data. 98 /// 99 /// Backends handle the target-special tables (plt, gp,...) by themselves. 100 /// Backend can put the data of the tables in SectionData directly 101 /// - LDSection.getSectionData can get the section data. 102 /// Or, backend can put the data into special data structure 103 /// - backend can maintain its own map<LDSection, table> to get the table 104 /// from given LDSection. 105 /// 106 /// @param pSection - the given LDSection 107 /// @param pRegion - the region to write out data 108 /// @return the size of the table in the file. 109 uint64_t emitSectionData(const LDSection& pSection, 110 MemoryRegion& pRegion) const; 111 112 void sizeNamePools(const Module& pModule, bool pIsStaticLink); 113 114 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 115 void emitDynNamePools(const Module& pModule, MemoryArea& pOut); 116 117 118 MipsGOT& getGOT(); 119 const MipsGOT& getGOT() const; 120 121 OutputRelocSection& getRelDyn(); 122 const OutputRelocSection& getRelDyn() const; 123 124 /// getTargetSectionOrder - compute the layout order of ARM target sections 125 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 126 127 /// finalizeSymbol - finalize the symbol value 128 bool finalizeTargetSymbols(FragmentLinker& pLinker); 129 130 /// allocateCommonSymbols - allocate common symbols in the corresponding 131 /// sections. 132 bool allocateCommonSymbols(Module& pModule); 133 134private: 135 void scanLocalReloc(Relocation& pReloc, FragmentLinker& pLinker); 136 137 void scanGlobalReloc(Relocation& pReloc, FragmentLinker& pLinker); 138 139 void defineGOTSymbol(FragmentLinker& pLinker); 140 141 /// emitSymbol32 - emit an ELF32 symbol, override parent's function 142 void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32, 143 LDSymbol& pSymbol, 144 char* pStrtab, 145 size_t pStrtabsize, 146 size_t pSymtabIdx); 147 148 /// getRelEntrySize - the size in BYTE of rel type relocation 149 size_t getRelEntrySize() 150 { return 8; } 151 152 /// getRelEntrySize - the size in BYTE of rela type relocation 153 size_t getRelaEntrySize() 154 { return 12; } 155 156 /// doCreateProgramHdrs - backend can implement this function to create the 157 /// target-dependent segments 158 virtual void doCreateProgramHdrs(Module& pModule, 159 const FragmentLinker& pLinker); 160 161private: 162 RelocationFactory* m_pRelocFactory; 163 164 MipsGOT* m_pGOT; // .got 165 OutputRelocSection* m_pRelDyn; // .rel.dyn 166 167 MipsELFDynamic* m_pDynamic; 168 LDSymbol* m_pGOTSymbol; 169 LDSymbol* m_pGpDispSymbol; 170 171 std::vector<LDSymbol*> m_GlobalGOTSyms; 172 173private: 174 /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry. 175 bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const; 176 177}; 178 179} // namespace of mcld 180 181#endif 182 183