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