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 MCLDInfo; 22 class MCLinker; 23 class Output; 24 class SectionMap; 25 26 27 //===----------------------------------------------------------------------===// 28 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format 29 /// 30 class ARMGNULDBackend : public GNULDBackend 31 { 32 public: 33 ARMGNULDBackend(); 34 ~ARMGNULDBackend(); 35 public: 36 typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList; 37 38 /** \enum ReservedEntryType 39 * \brief The reserved entry type of reserved space in ResolveInfo. 40 * 41 * This is used for sacnRelocation to record what kinds of entries are 42 * reserved for this resolved symbol 43 * 44 * In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction. 45 * GOT may needs a corresponding relocation to relocate itself, so we 46 * separate GOT to two situations: GOT and GOTRel. Besides, for the same 47 * symbol, there might be two kinds of entries reserved for different location. 48 * For example, reference to the same symbol, one may use GOT and the other may 49 * use dynamic relocation. 50 * 51 * bit: 3 2 1 0 52 * | PLT | GOTRel | GOT | Rel | 53 * 54 * value Name - Description 55 * 56 * 0000 None - no reserved entry 57 * 0001 ReserveRel - reserve an dynamic relocation entry 58 * 0010 ReserveGOT - reserve an GOT entry 59 * 0011 GOTandRel - For different relocation, we've reserved GOT and 60 * Rel for different location. 61 * 0100 GOTRel - reserve an GOT entry and the corresponding Dyncamic 62 * relocation entry which relocate this GOT entry 63 * 0101 GOTRelandRel - For different relocation, we've reserved GOTRel 64 * and relocation entry for different location. 65 * 1000 ReservePLT - reserve an PLT entry and the corresponding GOT, 66 * Dynamic relocation entries 67 * 1001 PLTandRel - For different relocation, we've reserved PLT and 68 * Rel for different location. 69 */ 70 enum ReservedEntryType { 71 None = 0, 72 ReserveRel = 1, 73 ReserveGOT = 2, 74 GOTandRel = 3, 75 GOTRel = 4, 76 GOTRelandRel = 5, 77 ReservePLT = 8, 78 PLTandRel = 9 79 }; 80 81 public: 82 /// initTargetSectionMap - initialize target dependent section mapping 83 bool initTargetSectionMap(SectionMap& pSectionMap); 84 85 /// initTargetSections - initialize target dependent sections in output. 86 void initTargetSections(MCLinker& pLinker); 87 88 /// initTargetSymbols - initialize target dependent symbols in output. 89 void initTargetSymbols(MCLinker& pLinker); 90 91 /// initRelocFactory - create and initialize RelocationFactory 92 bool initRelocFactory(const MCLinker& pLinker); 93 94 /// getRelocFactory 95 RelocationFactory* getRelocFactory(); 96 97 /// scanRelocation - determine the empty entries are needed or not and create 98 /// the empty entries if needed. 99 /// For ARM, following entries are check to create: 100 /// - GOT entry (for .got section) 101 /// - PLT entry (for .plt section) 102 /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) 103 void scanRelocation(Relocation& pReloc, 104 const LDSymbol& pInputSym, 105 MCLinker& pLinker, 106 const MCLDInfo& pLDInfo, 107 const Output& pOutput); 108 109 uint32_t machine() const 110 { return llvm::ELF::EM_ARM; } 111 112 /// OSABI - the value of e_ident[EI_OSABI] 113 virtual uint8_t OSABI() const 114 { return llvm::ELF::ELFOSABI_NONE; } 115 116 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 117 virtual uint8_t ABIVersion() const 118 { return 0x0; } 119 120 /// flags - the value of ElfXX_Ehdr::e_flags 121 virtual uint64_t flags() const 122 { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); } 123 124 bool isLittleEndian() const 125 { return true; } 126 127 unsigned int bitclass() const 128 { return 32; } 129 130 /// doPreLayout - Backend can do any needed modification before layout 131 void doPreLayout(const Output& pOutput, 132 const MCLDInfo& pInfo, 133 MCLinker& pLinker); 134 135 /// doPostLayout -Backend can do any needed modification after layout 136 void doPostLayout(const Output& pOutput, 137 const MCLDInfo& pInfo, 138 MCLinker& pLinker); 139 140 /// dynamic - the dynamic section of the target machine. 141 /// Use co-variant return type to return its own dynamic section. 142 ARMELFDynamic& dynamic(); 143 144 /// dynamic - the dynamic section of the target machine. 145 /// Use co-variant return type to return its own dynamic section. 146 const ARMELFDynamic& dynamic() const; 147 148 149 /// emitSectionData - write out the section data into the memory region. 150 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 151 /// call back target backend to emit the data. 152 /// 153 /// Backends handle the target-special tables (plt, gp,...) by themselves. 154 /// Backend can put the data of the tables in MCSectionData directly 155 /// - LDSection.getSectionData can get the section data. 156 /// Or, backend can put the data into special data structure 157 /// - backend can maintain its own map<LDSection, table> to get the table 158 /// from given LDSection. 159 /// 160 /// @param pOutput - the output file 161 /// @param pSection - the given LDSection 162 /// @param pInfo - all options in the command line. 163 /// @param pRegion - the region to write out data 164 /// @return the size of the table in the file. 165 uint64_t emitSectionData(const Output& pOutput, 166 const LDSection& pSection, 167 const MCLDInfo& pInfo, 168 MemoryRegion& pRegion) const; 169 170 ARMGOT& getGOT(); 171 172 const ARMGOT& getGOT() const; 173 174 ARMPLT& getPLT(); 175 176 const ARMPLT& getPLT() const; 177 178 OutputRelocSection& getRelDyn(); 179 180 const OutputRelocSection& getRelDyn() const; 181 182 OutputRelocSection& getRelPLT(); 183 184 const OutputRelocSection& getRelPLT() const; 185 186 /// getTargetSectionOrder - compute the layout order of ARM target sections 187 unsigned int getTargetSectionOrder(const Output& pOutput, 188 const LDSection& pSectHdr) const; 189 190 /// finalizeSymbol - finalize the symbol value 191 /// If the symbol's reserved field is not zero, MCLinker will call back this 192 /// function to ask the final value of the symbol 193 bool finalizeSymbol(LDSymbol& pSymbol) const; 194 195 /// allocateCommonSymbols - allocate common symbols in the corresponding 196 /// sections. 197 bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const; 198 199 /// readSection - read target dependent sections 200 bool readSection(Input& pInput, 201 MCLinker& pLinker, 202 LDSection& pInputSectHdr); 203 204 public: 205 bool isSymbolPreemptible(const ResolveInfo& pSym, 206 const MCLDInfo& pLDInfo, 207 const Output& pOutput) const; 208 209 bool isPIC(const MCLDInfo& pLDInfo, const Output& pOutput) const; 210 211 private: 212 void scanLocalReloc(Relocation& pReloc, 213 const LDSymbol& pInputSym, 214 MCLinker& pLinker, 215 const MCLDInfo& pLDInfo, 216 const Output& pOutput); 217 218 void scanGlobalReloc(Relocation& pReloc, 219 const LDSymbol& pInputSym, 220 MCLinker& pLinker, 221 const MCLDInfo& pLDInfo, 222 const Output& pOutput); 223 224 bool isSymbolNeedsPLT(const ResolveInfo& pSym, 225 const MCLDInfo& pLDInfo, 226 const Output& pOutput) const; 227 228 bool isSymbolNeedsDynRel(const ResolveInfo& pSym, 229 const Output& pOutput, 230 bool isAbsReloc) const; 231 232 233 void checkValidReloc(Relocation& pReloc, 234 const MCLDInfo& pLDInfo, 235 const Output& pOutput) const; 236 237 /// updateAddend - update addend value of the relocation if the 238 /// the target symbol is a section symbol. Addend is the offset 239 /// in the section. This value should be updated after section 240 /// merged. 241 void updateAddend(Relocation& pReloc, 242 const LDSymbol& pInputSym, 243 const Layout& pLayout) const; 244 245 void createARMGOT(MCLinker& pLinker, const Output& pOutput); 246 247 /// createARMPLTandRelPLT - create PLT and RELPLT sections. 248 /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two 249 /// sections should be create together. 250 void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput); 251 252 void createARMRelDyn(MCLinker& pLinker, const Output& pOutput); 253 254 ELFFileFormat* getOutputFormat(const Output& pOutput) const; 255 256 private: 257 RelocationFactory* m_pRelocFactory; 258 ARMGOT* m_pGOT; 259 ARMPLT* m_pPLT; 260 /// m_RelDyn - dynamic relocation table of .rel.dyn 261 OutputRelocSection* m_pRelDyn; 262 /// m_RelPLT - dynamic relocation table of .rel.plt 263 OutputRelocSection* m_pRelPLT; 264 265 ARMELFDynamic* m_pDynamic; 266 LDSymbol* m_pGOTSymbol; 267 268 // variable name : ELF 269 LDSection* m_pEXIDX; // .ARM.exidx 270 LDSection* m_pEXTAB; // .ARM.extab 271 LDSection* m_pAttributes; // .ARM.attributes 272 // LDSection* m_pPreemptMap; // .ARM.preemptmap 273 // LDSection* m_pDebugOverlay; // .ARM.debug_overlay 274 // LDSection* m_pOverlayTable; // .ARM.overlay_table 275 }; 276 277 //===----------------------------------------------------------------------===// 278 /// ARMMachOLDBackend - linker backend of ARM target of MachO format 279 /// 280 /** 281 class ARMMachOLDBackend : public DarwinARMLDBackend 282 { 283 public: 284 ARMMachOLDBackend(); 285 ~ARMMachOLDBackend(); 286 287 private: 288 MCMachOTargetArchiveReader *createTargetArchiveReader() const; 289 MCMachOTargetObjectReader *createTargetObjectReader() const; 290 MCMachOTargetObjectWriter *createTargetObjectWriter() const; 291 292 }; 293 **/ 294 } // namespace of mcld 295 296 #endif 297