1 //===- AArch64LDBackend.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_AARCH64_AARCH64LDBACKEND_H_ 10 #define TARGET_AARCH64_AARCH64LDBACKEND_H_ 11 12 #include "AArch64ELFDynamic.h" 13 #include "AArch64GOT.h" 14 #include "AArch64PLT.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 GNUInfo; 23 24 //===----------------------------------------------------------------------===// 25 /// AArch64GNULDBackend - linker backend of AArch64 target of GNU ELF format 26 /// 27 class AArch64GNULDBackend : public GNULDBackend { 28 public: 29 static constexpr int64_t MAX_FWD_BRANCH_OFFSET = (((1 << 25) - 1) << 2); 30 static constexpr int64_t MAX_BWD_BRANCH_OFFSET = (-((1 << 25) << 2)); 31 32 static constexpr int64_t MAX_ADRP_IMM = (1 << 20) - 1; 33 static constexpr int64_t MIN_ADRP_IMM = -(1 << 20); 34 35 public: 36 AArch64GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 37 ~AArch64GNULDBackend(); 38 39 public: 40 /// initTargetSections - initialize target dependent sections in output. 41 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 42 43 /// initTargetSymbols - initialize target dependent symbols in output. 44 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 45 46 /// initRelocator - create and initialize Relocator. 47 bool initRelocator(); 48 49 /// getRelocator - return relocator. 50 const Relocator* getRelocator() const; 51 Relocator* getRelocator(); 52 53 /// doPreLayout - Backend can do any needed modification before layout 54 void doPreLayout(IRBuilder& pBuilder); 55 56 /// doPostLayout -Backend can do any needed modification after layout 57 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 58 59 /// dynamic - the dynamic section of the target machine. 60 /// Use co-variant return type to return its own dynamic section. 61 AArch64ELFDynamic& dynamic(); 62 63 /// dynamic - the dynamic section of the target machine. 64 /// Use co-variant return type to return its own dynamic section. 65 const AArch64ELFDynamic& dynamic() const; 66 67 /// emitSectionData - write out the section data into the memory region. 68 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 69 /// call back target backend to emit the data. 70 /// 71 /// Backends handle the target-special tables (plt, gp,...) by themselves. 72 /// Backend can put the data of the tables in SectionData directly 73 /// - LDSection.getSectionData can get the section data. 74 /// Or, backend can put the data into special data structure 75 /// - backend can maintain its own map<LDSection, table> to get the table 76 /// from given LDSection. 77 /// 78 /// @param pSection - the given LDSection 79 /// @param pConfig - all options in the command line. 80 /// @param pRegion - the region to write out data 81 /// @return the size of the table in the file. 82 uint64_t emitSectionData(const LDSection& pSection, 83 MemoryRegion& pRegion) const; 84 85 AArch64GOT& getGOT(); 86 const AArch64GOT& getGOT() const; 87 88 AArch64GOT& getGOTPLT(); 89 const AArch64GOT& getGOTPLT() const; 90 91 AArch64PLT& getPLT(); 92 const AArch64PLT& getPLT() const; 93 94 OutputRelocSection& getRelaDyn(); 95 const OutputRelocSection& getRelaDyn() const; 96 97 OutputRelocSection& getRelaPLT(); 98 const OutputRelocSection& getRelaPLT() const; 99 getGOTSymbol()100 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } getGOTSymbol()101 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 102 103 /// getTargetSectionOrder - compute the layout order of AArch64 target 104 /// sections 105 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 106 107 /// finalizeTargetSymbols - finalize the symbol value 108 bool finalizeTargetSymbols(); 109 110 /// mergeSection - merge target dependent sections 111 bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 112 113 /// readSection - read target dependent sections 114 bool readSection(Input& pInput, SectionData& pSD); 115 116 private: 117 void defineGOTSymbol(IRBuilder& pBuilder); 118 maxFwdBranchOffset()119 int64_t maxFwdBranchOffset() const { return MAX_FWD_BRANCH_OFFSET; } maxBwdBranchOffset()120 int64_t maxBwdBranchOffset() const { return MAX_BWD_BRANCH_OFFSET; } 121 122 void scanErrata(Module& pModule, 123 IRBuilder& pBuilder, 124 size_t& num_new_stubs, 125 size_t& stubs_strlen); 126 127 /// mayRelax - Backends should override this function if they need relaxation mayRelax()128 bool mayRelax() { return true; } 129 130 /// doRelax - Backend can orevride this function to add its relaxation 131 /// implementation. Return true if the output (e.g., .text) is "relaxed" 132 /// (i.e. layout is changed), and set pFinished to true if everything is fit, 133 /// otherwise set it to false. 134 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 135 136 /// initTargetStubs 137 bool initTargetStubs(); 138 139 /// getRelEntrySize - the size in BYTE of rel type relocation getRelEntrySize()140 size_t getRelEntrySize() { return 16; } 141 142 /// getRelEntrySize - the size in BYTE of rela type relocation getRelaEntrySize()143 size_t getRelaEntrySize() { return 24; } 144 145 /// doCreateProgramHdrs - backend can implement this function to create the 146 /// target-dependent segments 147 virtual void doCreateProgramHdrs(Module& pModule); 148 149 private: 150 Relocator* m_pRelocator; 151 152 AArch64GOT* m_pGOT; 153 AArch64GOT* m_pGOTPLT; 154 AArch64PLT* m_pPLT; 155 /// m_RelDyn - dynamic relocation table of .rel.dyn 156 OutputRelocSection* m_pRelaDyn; 157 /// m_RelPLT - dynamic relocation table of .rel.plt 158 OutputRelocSection* m_pRelaPLT; 159 160 /// m_pAttrData - attribute data in public ("aeabi") attribute subsection 161 // AArch64ELFAttributeData* m_pAttrData; 162 163 AArch64ELFDynamic* m_pDynamic; 164 LDSymbol* m_pGOTSymbol; 165 166 // variable name : ELF 167 // LDSection* m_pAttributes; // .ARM.attributes 168 // LDSection* m_pPreemptMap; // .AArch64.preemptmap 169 // LDSection* m_pDebugOverlay; // .AArch64.debug_overlay 170 // LDSection* m_pOverlayTable; // .AArch64.overlay_table 171 }; 172 173 } // namespace mcld 174 175 #endif // TARGET_AARCH64_AARCH64LDBACKEND_H_ 176