ARMLDBackend.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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 19namespace mcld { 20 21class ARMELFAttributeData; 22class LinkerConfig; 23class GNUInfo; 24 25//===----------------------------------------------------------------------===// 26/// ARMGNULDBackend - linker backend of ARM target of GNU ELF format 27/// 28class ARMGNULDBackend : public GNULDBackend 29{ 30public: 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 40public: 41 ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 42 ~ARMGNULDBackend(); 43 44public: 45 typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList; 46 47public: 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 ARMELFAttributeData& getAttributeData(); 107 const ARMELFAttributeData& getAttributeData() const; 108 109 LDSymbol* getGOTSymbol() { return m_pGOTSymbol; } 110 const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; } 111 112 /// getTargetSectionOrder - compute the layout order of ARM target sections 113 unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const; 114 115 /// finalizeTargetSymbols - finalize the symbol value 116 bool finalizeTargetSymbols(); 117 118 /// mergeSection - merge target dependent sections 119 bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection); 120 121 /// setUpReachedSectionsForGC - set the reference from section XXX to 122 /// .ARM.exidx.XXX to make sure GC correctly handle section exidx 123 void setUpReachedSectionsForGC(const Module& pModule, 124 GarbageCollection::SectionReachedListMap& pSectReachedListMap) const; 125 126 /// readSection - read target dependent sections 127 bool readSection(Input& pInput, SectionData& pSD); 128 129private: 130 void defineGOTSymbol(IRBuilder& pBuilder); 131 132 /// maxBranchOffset 133 /// FIXME: if we can handle arm attributes, we may refine this! 134 uint64_t maxBranchOffset() { return THM_MAX_FWD_BRANCH_OFFSET; } 135 136 /// mayRelax - Backends should override this function if they need relaxation 137 bool mayRelax() { return true; } 138 139 /// doRelax - Backend can orevride this function to add its relaxation 140 /// implementation. Return true if the output (e.g., .text) is "relaxed" 141 /// (i.e. layout is changed), and set pFinished to true if everything is fit, 142 /// otherwise set it to false. 143 bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished); 144 145 /// initTargetStubs 146 bool initTargetStubs(); 147 148 /// getRelEntrySize - the size in BYTE of rel type relocation 149 size_t getRelEntrySize() 150 { return 8; } 151 152 /// getRelEntrySize - the size in BYTE of rela type relocation 153 size_t getRelaEntrySize() 154 { assert(0 && "ARM backend with Rela type relocation\n"); return 12; } 155 156 /// doCreateProgramHdrs - backend can implement this function to create the 157 /// target-dependent segments 158 virtual void doCreateProgramHdrs(Module& pModule); 159 160private: 161 Relocator* m_pRelocator; 162 163 ARMGOT* m_pGOT; 164 ARMPLT* m_pPLT; 165 /// m_RelDyn - dynamic relocation table of .rel.dyn 166 OutputRelocSection* m_pRelDyn; 167 /// m_RelPLT - dynamic relocation table of .rel.plt 168 OutputRelocSection* m_pRelPLT; 169 170 /// m_pAttrData - attribute data in public ("aeabi") attribute subsection 171 ARMELFAttributeData* m_pAttrData; 172 173 ARMELFDynamic* m_pDynamic; 174 LDSymbol* m_pGOTSymbol; 175 LDSymbol* m_pEXIDXStart; 176 LDSymbol* m_pEXIDXEnd; 177 178 // variable name : ELF 179 LDSection* m_pEXIDX; // .ARM.exidx 180 LDSection* m_pEXTAB; // .ARM.extab 181 LDSection* m_pAttributes; // .ARM.attributes 182// LDSection* m_pPreemptMap; // .ARM.preemptmap 183// LDSection* m_pDebugOverlay; // .ARM.debug_overlay 184// LDSection* m_pOverlayTable; // .ARM.overlay_table 185}; 186} // namespace of mcld 187 188#endif 189 190