1 //===- ARMLDBackend.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_ARM_ARMLDBACKEND_H_ 10 #define TARGET_ARM_ARMLDBACKEND_H_ 11 12 #include "ARMELFDynamic.h" 13 #include "ARMException.h" 14 #include "ARMGOT.h" 15 #include "ARMPLT.h" 16 #include "mcld/LD/LDSection.h" 17 #include "mcld/Target/GNULDBackend.h" 18 #include "mcld/Target/OutputRelocSection.h" 19 20 namespace mcld { 21 22 class ARMELFAttributeData; 23 class GNUInfo; 24 class LinkerConfig; 25 26 //===----------------------------------------------------------------------===// 27 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format 28 /// 29 class ARMGNULDBackend : public GNULDBackend { 30 public: 31 // max branch offsets for ARM, THUMB, and THUMB2 32 static const int32_t ARM_MAX_FWD_BRANCH_OFFSET = ((((1 << 23) - 1) << 2) + 8); 33 static const int32_t ARM_MAX_BWD_BRANCH_OFFSET = ((-((1 << 23) << 2)) + 8); 34 static const int32_t THM_MAX_FWD_BRANCH_OFFSET = ((1 << 22) - 2 + 4); 35 static const int32_t THM_MAX_BWD_BRANCH_OFFSET = (-(1 << 22) + 4); 36 static const int32_t THM2_MAX_FWD_BRANCH_OFFSET = (((1 << 24) - 2) + 4); 37 static const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4); 38 39 public: 40 ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 41 ~ARMGNULDBackend(); 42 43 public: 44 typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList; 45 46 public: 47 /// initTargetSections - initialize target dependent sections in output. 48 void initTargetSections(Module& pModule, ObjectBuilder& pBuilder); 49 50 /// initTargetSymbols - initialize target dependent symbols in output. 51 void initTargetSymbols(IRBuilder& pBuilder, Module& pModule); 52 53 /// initRelocator - create and initialize Relocator. 54 bool initRelocator(); 55 56 /// getRelocator - return relocator. 57 const Relocator* getRelocator() const; 58 Relocator* getRelocator(); 59 60 /// doPreLayout - Backend can do any needed modification before layout 61 void doPreLayout(IRBuilder& pBuilder); 62 63 /// doPostLayout -Backend can do any needed modification after layout 64 void doPostLayout(Module& pModule, IRBuilder& pBuilder); 65 66 /// dynamic - the dynamic section of the target machine. 67 /// Use co-variant return type to return its own dynamic section. 68 ARMELFDynamic& dynamic(); 69 70 /// dynamic - the dynamic section of the target machine. 71 /// Use co-variant return type to return its own dynamic section. 72 const ARMELFDynamic& dynamic() const; 73 74 /// emitSectionData - write out the section data into the memory region. 75 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 76 /// call back target backend to emit the data. 77 /// 78 /// Backends handle the target-special tables (plt, gp,...) by themselves. 79 /// Backend can put the data of the tables in SectionData directly 80 /// - LDSection.getSectionData can get the section data. 81 /// Or, backend can put the data into special data structure 82 /// - backend can maintain its own map<LDSection, table> to get the table 83 /// from given LDSection. 84 /// 85 /// @param pSection - the given LDSection 86 /// @param pConfig - all options in the command line. 87 /// @param pRegion - the region to write out data 88 /// @return the size of the table in the file. 89 uint64_t emitSectionData(const LDSection& pSection, 90 MemoryRegion& pRegion) const; 91 92 ARMGOT& getGOT(); 93 const ARMGOT& getGOT() const; 94 95 ARMPLT& getPLT(); 96 const ARMPLT& getPLT() const; 97 98 OutputRelocSection& getRelDyn(); 99 const OutputRelocSection& getRelDyn() const; 100 101 OutputRelocSection& getRelPLT(); 102 const OutputRelocSection& getRelPLT() const; 103 104 ARMELFAttributeData& getAttributeData(); 105 const ARMELFAttributeData& getAttributeData() const; 106 107 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 108 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 109 110 /// getTargetSectionOrder - compute the layout order of ARM target sections 111 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 112 113 /// finalizeTargetSymbols - finalize the symbol value 114 bool finalizeTargetSymbols(); 115 116 /// preMergeSections - hooks to be executed before merging sections 117 virtual void preMergeSections(Module& pModule); 118 119 /// postMergeSections - hooks to be executed after merging sections 120 virtual void postMergeSections(Module& pModule); 121 122 /// mergeSection - merge target dependent sections 123 bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 124 125 /// setUpReachedSectionsForGC - set the reference from section XXX to 126 /// .ARM.exidx.XXX to make sure GC correctly handle section exidx 127 void setUpReachedSectionsForGC( 128 const Module& pModule, 129 GarbageCollection::SectionReachedListMap& pSectReachedListMap) const; 130 131 /// readSection - read target dependent sections 132 bool readSection(Input& pInput, SectionData& pSD); 133 134 /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 135 /// function pointer access 136 bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const; 137 138 private: 139 void defineGOTSymbol(IRBuilder& pBuilder); 140 141 /// maxFwdBranchOffset 142 int64_t maxFwdBranchOffset(); 143 /// maxBwdBranchOffset 144 int64_t maxBwdBranchOffset(); 145 146 /// mayRelax - Backends should override this function if they need relaxation 147 bool mayRelax() { return true; } 148 149 /// relax - the relaxation pass 150 virtual bool relax(Module& pModule, IRBuilder& pBuilder); 151 152 /// doRelax - Backend can orevride this function to add its relaxation 153 /// implementation. Return true if the output (e.g., .text) is "relaxed" 154 /// (i.e. layout is changed), and set pFinished to true if everything is fit, 155 /// otherwise set it to false. 156 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 157 158 /// initTargetStubs 159 bool initTargetStubs(); 160 161 /// getRelEntrySize - the size in BYTE of rel type relocation 162 size_t getRelEntrySize() { return 8; } 163 164 /// getRelEntrySize - the size in BYTE of rela type relocation 165 size_t getRelaEntrySize() { 166 assert(0 && "ARM backend with Rela type relocation\n"); 167 return 12; 168 } 169 170 /// doCreateProgramHdrs - backend can implement this function to create the 171 /// target-dependent segments 172 virtual void doCreateProgramHdrs(Module& pModule); 173 174 /// scanInputExceptionSections - scan exception-related input sections in 175 /// the Module, build the ARMExData, and reclaim GC'ed sections 176 void scanInputExceptionSections(Module& pModule); 177 178 /// scanInputExceptionSections - scan exception-related input sections in 179 /// the Input, build the ARMInputExMap, and reclaim GC'ed sections 180 void scanInputExceptionSections(Module& pModule, Input& pInput); 181 182 /// rewriteExceptionSection - rewrite the output .ARM.exidx section. 183 void rewriteARMExIdxSection(Module& pModule); 184 185 private: 186 Relocator* m_pRelocator; 187 188 ARMGOT* m_pGOT; 189 ARMPLT* m_pPLT; 190 /// m_RelDyn - dynamic relocation table of .rel.dyn 191 OutputRelocSection* m_pRelDyn; 192 /// m_RelPLT - dynamic relocation table of .rel.plt 193 OutputRelocSection* m_pRelPLT; 194 195 /// m_pAttrData - attribute data in public ("aeabi") attribute subsection 196 ARMELFAttributeData* m_pAttrData; 197 198 ARMELFDynamic* m_pDynamic; 199 LDSymbol* m_pGOTSymbol; 200 LDSymbol* m_pEXIDXStart; 201 LDSymbol* m_pEXIDXEnd; 202 203 // variable name : ELF 204 LDSection* m_pEXIDX; // .ARM.exidx 205 LDSection* m_pEXTAB; // .ARM.extab 206 LDSection* m_pAttributes; // .ARM.attributes 207 // LDSection* m_pPreemptMap; // .ARM.preemptmap 208 // LDSection* m_pDebugOverlay; // .ARM.debug_overlay 209 // LDSection* m_pOverlayTable; // .ARM.overlay_table 210 211 // m_ExData - exception handling section data structures 212 ARMExData m_ExData; 213 }; 214 } // namespace mcld 215 216 #endif // TARGET_ARM_ARMLDBACKEND_H_ 217