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