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