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 MCLDInfo; 22class MCLinker; 23class Output; 24class SectionMap; 25 26 27//===----------------------------------------------------------------------===// 28/// ARMGNULDBackend - linker backend of ARM target of GNU ELF format 29/// 30class ARMGNULDBackend : public GNULDBackend 31{ 32public: 33 ARMGNULDBackend(); 34 ~ARMGNULDBackend(); 35public: 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 81public: 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, const Output& pOutput); 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 const LDSection& pSection); 109 110 uint32_t machine() const 111 { return llvm::ELF::EM_ARM; } 112 113 /// OSABI - the value of e_ident[EI_OSABI] 114 virtual uint8_t OSABI() const 115 { return llvm::ELF::ELFOSABI_NONE; } 116 117 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 118 virtual uint8_t ABIVersion() const 119 { return 0x0; } 120 121 /// flags - the value of ElfXX_Ehdr::e_flags 122 virtual uint64_t flags() const 123 { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); } 124 125 bool isLittleEndian() const 126 { return true; } 127 128 unsigned int bitclass() const 129 { return 32; } 130 131 uint64_t defaultTextSegmentAddr() const 132 { return 0x8000; } 133 134 /// doPreLayout - Backend can do any needed modification before layout 135 void doPreLayout(const Output& pOutput, 136 const MCLDInfo& pInfo, 137 MCLinker& pLinker); 138 139 /// doPostLayout -Backend can do any needed modification after layout 140 void doPostLayout(const Output& pOutput, 141 const MCLDInfo& pInfo, 142 MCLinker& pLinker); 143 144 /// dynamic - the dynamic section of the target machine. 145 /// Use co-variant return type to return its own dynamic section. 146 ARMELFDynamic& dynamic(); 147 148 /// dynamic - the dynamic section of the target machine. 149 /// Use co-variant return type to return its own dynamic section. 150 const ARMELFDynamic& dynamic() const; 151 152 153 /// emitSectionData - write out the section data into the memory region. 154 /// When writers get a LDSection whose kind is LDFileFormat::Target, writers 155 /// call back target backend to emit the data. 156 /// 157 /// Backends handle the target-special tables (plt, gp,...) by themselves. 158 /// Backend can put the data of the tables in SectionData directly 159 /// - LDSection.getSectionData can get the section data. 160 /// Or, backend can put the data into special data structure 161 /// - backend can maintain its own map<LDSection, table> to get the table 162 /// from given LDSection. 163 /// 164 /// @param pOutput - the output file 165 /// @param pSection - the given LDSection 166 /// @param pInfo - all options in the command line. 167 /// @param pLayout - for comouting the size of fragment 168 /// @param pRegion - the region to write out data 169 /// @return the size of the table in the file. 170 uint64_t emitSectionData(const Output& pOutput, 171 const LDSection& pSection, 172 const MCLDInfo& pInfo, 173 const Layout& pLayout, 174 MemoryRegion& pRegion) const; 175 176 ARMGOT& getGOT(); 177 178 const ARMGOT& getGOT() const; 179 180 ARMPLT& getPLT(); 181 182 const ARMPLT& getPLT() const; 183 184 OutputRelocSection& getRelDyn(); 185 186 const OutputRelocSection& getRelDyn() const; 187 188 OutputRelocSection& getRelPLT(); 189 190 const OutputRelocSection& getRelPLT() const; 191 192 /// getTargetSectionOrder - compute the layout order of ARM target sections 193 unsigned int getTargetSectionOrder(const Output& pOutput, 194 const LDSection& pSectHdr, 195 const MCLDInfo& pInfo) const; 196 197 /// finalizeTargetSymbols - finalize the symbol value 198 bool finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput); 199 200 /// readSection - read target dependent sections 201 bool readSection(Input& pInput, 202 MCLinker& pLinker, 203 LDSection& pInputSectHdr); 204 205private: 206 void scanLocalReloc(Relocation& pReloc, 207 const LDSymbol& pInputSym, 208 MCLinker& pLinker, 209 const MCLDInfo& pLDInfo, 210 const Output& pOutput); 211 212 void scanGlobalReloc(Relocation& pReloc, 213 const LDSymbol& pInputSym, 214 MCLinker& pLinker, 215 const MCLDInfo& pLDInfo, 216 const Output& pOutput); 217 218 void checkValidReloc(Relocation& pReloc, 219 const MCLDInfo& pLDInfo, 220 const Output& pOutput) const; 221 222 /// addCopyReloc - add a copy relocation into .rel.dyn for pSym 223 /// @param pSym - A resolved copy symbol that defined in BSS section 224 void addCopyReloc(ResolveInfo& pSym); 225 226 /// defineSymbolforCopyReloc - allocate a space in BSS section and 227 /// and force define the copy of pSym to BSS section 228 /// @return the output LDSymbol of the copy symbol 229 LDSymbol& defineSymbolforCopyReloc(MCLinker& pLinker, 230 const ResolveInfo& pSym); 231 232 /// updateAddend - update addend value of the relocation if the 233 /// the target symbol is a section symbol. Addend is the offset 234 /// in the section. This value should be updated after section 235 /// merged. 236 void updateAddend(Relocation& pReloc, 237 const LDSymbol& pInputSym, 238 const Layout& pLayout) const; 239 240 void createARMGOT(MCLinker& pLinker, const Output& pOutput); 241 242 /// createARMPLTandRelPLT - create PLT and RELPLT sections. 243 /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two 244 /// sections should be create together. 245 void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput); 246 247 void createARMRelDyn(MCLinker& pLinker, const Output& pOutput); 248 249private: 250 RelocationFactory* m_pRelocFactory; 251 ARMGOT* m_pGOT; 252 ARMPLT* m_pPLT; 253 /// m_RelDyn - dynamic relocation table of .rel.dyn 254 OutputRelocSection* m_pRelDyn; 255 /// m_RelPLT - dynamic relocation table of .rel.plt 256 OutputRelocSection* m_pRelPLT; 257 258 ARMELFDynamic* m_pDynamic; 259 LDSymbol* m_pGOTSymbol; 260 261 // variable name : ELF 262 LDSection* m_pEXIDX; // .ARM.exidx 263 LDSection* m_pEXTAB; // .ARM.extab 264 LDSection* m_pAttributes; // .ARM.attributes 265// LDSection* m_pPreemptMap; // .ARM.preemptmap 266// LDSection* m_pDebugOverlay; // .ARM.debug_overlay 267// LDSection* m_pOverlayTable; // .ARM.overlay_table 268}; 269 270//===----------------------------------------------------------------------===// 271/// ARMMachOLDBackend - linker backend of ARM target of MachO format 272/// 273/** 274class ARMMachOLDBackend : public DarwinARMLDBackend 275{ 276public: 277 ARMMachOLDBackend(); 278 ~ARMMachOLDBackend(); 279 280private: 281 MCMachOTargetArchiveReader *createTargetArchiveReader() const; 282 MCMachOTargetObjectReader *createTargetObjectReader() const; 283 MCMachOTargetObjectWriter *createTargetObjectWriter() const; 284 285}; 286**/ 287} // namespace of mcld 288 289#endif 290 291