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 <mcld/LD/LDSection.h> 16 #include <mcld/Target/GNULDBackend.h> 17 #include <mcld/Target/OutputRelocSection.h> 18 19 namespace mcld { 20 21 class LinkerConfig; 22 class HexagonGNUInfo; 23 24 //===----------------------------------------------------------------------===// 25 /// HexagonLDBackend - linker backend of Hexagon target of GNU ELF format 26 /// 27 class HexagonLDBackend : public GNULDBackend 28 { 29 public: 30 HexagonLDBackend(const LinkerConfig& pConfig, HexagonGNUInfo* pInfo); 31 32 ~HexagonLDBackend(); 33 34 uint32_t machine() const; 35 36 HexagonGOT& getGOT(); 37 38 const HexagonGOT& getGOT() const; 39 40 HexagonPLT& getPLT(); 41 42 const HexagonPLT& getPLT() const; 43 44 /// preLayout - Backend can do any needed modification before layout 45 void doPreLayout(IRBuilder& pBuilder); 46 47 /// postLayout - Backend can do any needed modification after layout 48 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 49 50 /// dynamic - the dynamic section of the target machine. 51 /// Use co-variant return type to return its own dynamic section. 52 HexagonELFDynamic& dynamic(); 53 54 /// dynamic - the dynamic section of the target machine. 55 /// Use co-variant return type to return its own dynamic section. 56 const HexagonELFDynamic& dynamic() const; 57 58 /// emitSectionData - write out the section data into the memory region. 59 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 60 /// call back target backend to emit the data. 61 /// 62 /// Backends handle the target-special tables (plt, gp,...) by themselves. 63 /// Backend can put the data of the tables in MCSectionData directly 64 /// - LDSection.getSectionData can get the section data. 65 /// Or, backend can put the data into special data structure 66 /// - backend can maintain its own map<LDSection, table> to get the table 67 /// from given LDSection. 68 /// 69 /// @param pSection - the given LDSection 70 /// @param pLayout - for comouting the size of fragment 71 /// @param pRegion - the region to write out data 72 /// @return the size of the table in the file. 73 uint64_t emitSectionData(const LDSection& pSection, 74 MemoryRegion& pRegion) const; 75 76 /// initRelocator - create and initialize Relocator. 77 bool initRelocator(); 78 79 /// getRelocator - return relocator. 80 Relocator* getRelocator(); 81 getSymDesc(uint16_t shndx)82 ResolveInfo::Desc getSymDesc(uint16_t shndx) const 83 { 84 if (shndx >= llvm::ELF::SHN_HEXAGON_SCOMMON && 85 shndx <= llvm::ELF::SHN_HEXAGON_SCOMMON_8) 86 return ResolveInfo::Common; 87 return ResolveInfo::NoneDesc; 88 } 89 90 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 91 92 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 93 94 /// scanRelocation - determine the empty entries are needed or not and create 95 /// the empty entries if needed. 96 /// For Hexagon, following entries are check to create: 97 /// - GOT entry (for .got and .got.plt sections) 98 /// - PLT entry (for .plt section) 99 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 100 void scanRelocation(Relocation& pReloc, 101 IRBuilder& pBuilder, 102 Module& pModule, 103 LDSection& pSection); 104 105 OutputRelocSection& getRelDyn(); 106 107 const OutputRelocSection& getRelDyn() const; 108 109 OutputRelocSection& getRelPLT(); 110 111 const OutputRelocSection& getRelPLT() const; 112 113 /// getTargetSectionOrder - compute the layout order of Hexagon target section 114 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 115 116 /// finalizeTargetSymbols - finalize the symbol value 117 bool finalizeTargetSymbols(); 118 119 private: 120 121 /// getRelEntrySize - the size in BYTE of rel type relocation getRelEntrySize()122 size_t getRelEntrySize() 123 { return 8; } 124 125 /// getRelEntrySize - the size in BYTE of rela type relocation getRelaEntrySize()126 size_t getRelaEntrySize() 127 { return 12; } 128 129 /// doCreateProgramHdrs - backend can implement this function to create the 130 /// target-dependent segments 131 void doCreateProgramHdrs(Module& pModule); 132 133 private: 134 Relocator* m_pRelocator; 135 HexagonGOT* m_pGOT; 136 HexagonPLT* m_pPLT; 137 /// m_RelDyn - dynamic relocation table of .rel.dyn 138 OutputRelocSection* m_pRelDyn; 139 /// m_RelPLT - dynamic relocation table of .rel.plt 140 OutputRelocSection* m_pRelPLT; 141 142 HexagonELFDynamic* m_pDynamic; 143 LDSymbol* m_pGOTSymbol; 144 LDSymbol* m_pBSSEnd; 145 }; 146 } // namespace of mcld 147 148 #endif 149 150