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 HEXAGON_LDBACKEND_H 10 #define HEXAGON_LDBACKEND_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 Relocator* getRelocator(); 87 88 ResolveInfo::Desc getSymDesc(uint16_t shndx) const 89 { 90 if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON && 91 shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8) 92 return ResolveInfo::Common; 93 return ResolveInfo::NoneDesc; 94 } 95 96 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 97 98 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 99 100 bool initBRIslandFactory(); 101 102 bool initStubFactory(); 103 104 bool mayRelax() { return true; } 105 106 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 107 108 bool initTargetStubs(); 109 110 OutputRelocSection& getRelaDyn(); 111 112 const OutputRelocSection& getRelaDyn() const; 113 114 HexagonGOTPLT& getGOTPLT(); 115 116 const HexagonGOTPLT& getGOTPLT() const; 117 118 OutputRelocSection& getRelaPLT(); 119 120 const OutputRelocSection& getRelaPLT() const; 121 122 /// getTargetSectionOrder - compute the layout order of Hexagon target section 123 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 124 125 /// finalizeTargetSymbols - finalize the symbol value 126 bool finalizeTargetSymbols(); 127 128 /// mergeSection - merge target dependent sections 129 bool mergeSection(Module& pModule, LDSection& pSection); 130 131 /// readSection - read target dependent sections 132 bool readSection(Input& pInput, SectionData& pSD); 133 134 bool MoveCommonData(SectionData &pFrom, SectionData &pTo); 135 136 bool MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo); 137 138 bool SetSDataSection(); 139 140 uint32_t getGP() { return m_psdata->addr(); } 141 142 Relocation::Type getCopyRelType() const { return m_CopyRel; } 143 144 virtual uint32_t getGOTSymbolAddr() { 145 return m_pGOTSymbol->value(); 146 } 147 148 149 protected: 150 void defineGOTSymbol(IRBuilder& pBuilder, Fragment&); 151 152 private: 153 /// getRelEntrySize - the size in BYTE of rela type relocation 154 size_t getRelEntrySize() 155 { return 0; } 156 157 /// getRelaEntrySize - the size in BYTE of rela type relocation 158 size_t getRelaEntrySize() 159 { return 12; } 160 161 /// doCreateProgramHdrs - backend can implement this function to create the 162 /// target-dependent segments 163 void doCreateProgramHdrs(Module& pModule); 164 165 uint64_t maxBranchOffset() { return ~(~0 << 6); } 166 167 virtual void setGOTSectionSize(IRBuilder& pBuilder); 168 169 virtual uint64_t emitGOTSectionData(MemoryRegion& pRegion) const; 170 171 virtual uint64_t emitGOTPLTSectionData(MemoryRegion& pRegion, 172 const ELFFileFormat* FileFormat) const; 173 174 virtual void setRelaDynSize(); 175 virtual void setRelaPLTSize(); 176 177 private: 178 Relocator* m_pRelocator; 179 HexagonGOT* m_pGOT; 180 HexagonGOTPLT* m_pGOTPLT; 181 HexagonPLT* m_pPLT; 182 /// m_RelaDyn - dynamic relocation table of .rela.dyn 183 OutputRelocSection* m_pRelaDyn; 184 /// m_RelaPLT - dynamic relocation table of .rela.plt 185 OutputRelocSection* m_pRelaPLT; 186 187 HexagonELFDynamic* m_pDynamic; 188 189 LDSection* m_psdata; 190 LDSection* m_pscommon_1; 191 LDSection* m_pscommon_2; 192 LDSection* m_pscommon_4; 193 LDSection* m_pscommon_8; 194 LDSection* m_pstart; 195 LDSymbol* m_psdabase; 196 197 LDSymbol* m_pGOTSymbol; 198 LDSymbol* m_pBSSEnd; 199 Relocation::Type m_CopyRel; 200 }; 201 } // namespace of mcld 202 203 #endif 204 205