1 //===- HexagonLDBackend.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_HEXAGON_HEXAGONLDBACKEND_H 10 #define TARGET_HEXAGON_HEXAGONLDBACKEND_H 11 12 #include "HexagonELFDynamic.h" 13 #include "HexagonGOT.h" 14 #include "HexagonPLT.h" 15 #include "HexagonGOTPLT.h" 16 #include <mcld/IRBuilder.h> 17 #include <mcld/LinkerConfig.h> 18 #include <mcld/LD/LDSection.h> 19 #include <mcld/Object/ObjectBuilder.h> 20 #include <mcld/Target/GNULDBackend.h> 21 #include <mcld/Target/OutputRelocSection.h> 22 23 namespace mcld { 24 25 class LinkerConfig; 26 class HexagonGNUInfo; 27 28 //===----------------------------------------------------------------------===// 29 /// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format 30 /// 31 class HexagonLDBackend : public GNULDBackend 32 { 33 public: 34 HexagonLDBackend(const LinkerConfig& pConfig, HexagonGNUInfo* pInfo); 35 36 ~HexagonLDBackend(); 37 38 uint32_t machine() const; 39 40 HexagonGOT& getGOT(); 41 42 const HexagonGOT& getGOT() const; 43 44 HexagonPLT& getPLT(); 45 46 const HexagonPLT& getPLT() const; 47 48 /// preLayout - Backend can do any needed modification before layout 49 void doPreLayout(IRBuilder& pBuilder); 50 51 bool allocateCommonSymbols(Module& pModule); 52 53 /// postLayout - Backend can do any needed modification after layout 54 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 55 56 /// dynamic - the dynamic section of the target machine. 57 /// Use co-variant return type to return its own dynamic section. 58 HexagonELFDynamic& dynamic(); 59 60 /// dynamic - the dynamic section of the target machine. 61 /// Use co-variant return type to return its own dynamic section. 62 const HexagonELFDynamic& dynamic() const; 63 64 /// emitSectionData - write out the section data into the memory region. 65 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 66 /// call back target backend to emit the data. 67 /// 68 /// Backends handle the target-special tables (plt, gp,...) by themselves. 69 /// Backend can put the data of the tables in MCSectionData directly 70 /// - LDSection.getSectionData can get the section data. 71 /// Or, backend can put the data into special data structure 72 /// - backend can maintain its own map<LDSection, table> to get the table 73 /// from given LDSection. 74 /// 75 /// @param pSection - the given LDSection 76 /// @param pLayout - for comouting the size of fragment 77 /// @param pRegion - the region to write out data 78 /// @return the size of the table in the file. 79 uint64_t emitSectionData(const LDSection& pSection, 80 MemoryRegion& pRegion) const; 81 82 /// initRelocator - create and initialize Relocator. 83 bool initRelocator(); 84 85 /// getRelocator - return relocator. 86 const Relocator* getRelocator() const; 87 Relocator* getRelocator(); 88 89 ResolveInfo::Desc getSymDesc(uint16_t shndx) const 90 { 91 if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON && 92 shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8) 93 return ResolveInfo::Common; 94 return ResolveInfo::NoneDesc; 95 } 96 97 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 98 99 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 100 101 bool initBRIslandFactory(); 102 103 bool initStubFactory(); 104 105 bool mayRelax() { return true; } 106 107 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 108 109 bool initTargetStubs(); 110 111 OutputRelocSection& getRelaDyn(); 112 113 const OutputRelocSection& getRelaDyn() const; 114 115 HexagonGOTPLT& getGOTPLT(); 116 117 const HexagonGOTPLT& getGOTPLT() const; 118 119 OutputRelocSection& getRelaPLT(); 120 121 const OutputRelocSection& getRelaPLT() const; 122 123 /// getTargetSectionOrder - compute the layout order of Hexagon target section 124 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 125 126 /// finalizeTargetSymbols - finalize the symbol value 127 bool finalizeTargetSymbols(); 128 129 /// mergeSection - merge target dependent sections 130 bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 131 132 /// readSection - read target dependent sections 133 bool readSection(Input& pInput, SectionData& pSD); 134 135 bool MoveCommonData(SectionData &pFrom, SectionData &pTo); 136 137 bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo); 138 139 bool SetSDataSection(); 140 141 uint32_t getGP() { return m_psdata->addr(); } 142 143 Relocation::Type getCopyRelType() const { return m_CopyRel; } 144 145 virtual uint32_t getGOTSymbolAddr() { 146 return m_pGOTSymbol->value(); 147 } 148 149 150 protected: 151 void defineGOTSymbol(IRBuilder& pBuilder, Fragment&); 152 153 private: 154 /// getRelEntrySize - the size in BYTE of rela type relocation 155 size_t getRelEntrySize() 156 { return 0; } 157 158 /// getRelaEntrySize - the size in BYTE of rela type relocation 159 size_t getRelaEntrySize() 160 { return 12; } 161 162 /// doCreateProgramHdrs - backend can implement this function to create the 163 /// target-dependent segments 164 void doCreateProgramHdrs(Module& pModule); 165 166 /// maxFwdBranchOffset 167 int64_t maxFwdBranchOffset() { return ~(~0 << 6); } 168 169 virtual void setGOTSectionSize(IRBuilder& pBuilder); 170 171 virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 172 173 virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 174 const ELFFileFormat* FileFormat) const; 175 176 virtual void setRelaDynSize(); 177 virtual void setRelaPLTSize(); 178 179 private: 180 Relocator* m_pRelocator; 181 HexagonGOT* m_pGOT; 182 HexagonGOTPLT* m_pGOTPLT; 183 HexagonPLT* m_pPLT; 184 /// m_RelaDyn - dynamic relocation table of .rela.dyn 185 OutputRelocSection* m_pRelaDyn; 186 /// m_RelaPLT - dynamic relocation table of .rela.plt 187 OutputRelocSection* m_pRelaPLT; 188 189 HexagonELFDynamic* m_pDynamic; 190 191 LDSection* m_psdata; 192 LDSection* m_pscommon_1; 193 LDSection* m_pscommon_2; 194 LDSection* m_pscommon_4; 195 LDSection* m_pscommon_8; 196 LDSection* m_pstart; 197 LDSymbol* m_psdabase; 198 199 LDSymbol* m_pGOTSymbol; 200 LDSymbol* m_pBSSEnd; 201 Relocation::Type m_CopyRel; 202 }; 203 } // namespace of mcld 204 205 #endif 206 207