1 //===- GNULDBackend.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_TARGET_GNU_LDBACKEND_H 10 #define MCLD_TARGET_GNU_LDBACKEND_H 11 #ifdef ENABLE_UNITTEST 12 #include <gtest.h> 13 #endif 14 15 #include <llvm/Support/ELF.h> 16 #include <mcld/ADT/HashTable.h> 17 #include <mcld/ADT/HashEntry.h> 18 #include <mcld/LD/ELFDynObjReader.h> 19 #include <mcld/LD/ELFDynObjWriter.h> 20 #include <mcld/LD/ELFObjectReader.h> 21 #include <mcld/LD/ELFObjectWriter.h> 22 #include <mcld/LD/ELFDynObjFileFormat.h> 23 #include <mcld/LD/ELFExecFileFormat.h> 24 #include <mcld/LD/ELFSegment.h> 25 #include <mcld/LD/GNUArchiveReader.h> 26 #include <mcld/Support/GCFactory.h> 27 #include <mcld/Target/ELFDynamic.h> 28 #include <mcld/Target/TargetLDBackend.h> 29 #include <mcld/LD/ELFSegmentFactory.h> 30 31 namespace mcld 32 { 33 34 struct SymCompare 35 { 36 bool operator()(const LDSymbol* X, const LDSymbol* Y) const 37 { return (X==Y); } 38 }; 39 40 struct PtrHash 41 { 42 size_t operator()(const LDSymbol* pKey) const 43 { 44 return (unsigned((uintptr_t)pKey) >> 4) ^ 45 (unsigned((uintptr_t)pKey) >> 9); 46 } 47 }; 48 49 class MCLDInfo; 50 class Layout; 51 class SymbolCategory; 52 53 /** \class GNULDBackend 54 * \brief GNULDBackend provides a common interface for all GNU Unix-OS 55 * LDBackend. 56 */ 57 class GNULDBackend : public TargetLDBackend 58 { 59 // These dynamic section tags are GNU extension. 60 enum { 61 DT_RELACOUNT = 0x6ffffff9, 62 DT_RELCOUNT = 0x6ffffffa, 63 DT_FLAGS_1 = 0x6ffffffb, 64 DT_VERDEF = 0x6ffffffc, 65 DT_VERDEFNUM = 0x6ffffffd, 66 DT_VERNEED = 0x6ffffffe, 67 DT_VERNEEDNUM = 0x6fffffff 68 }; 69 70 protected: 71 // Based on Kind in LDFileFormat to define basic section orders for ELF, and 72 // refer gold linker to add more enumerations to handle Regular and BSS kind 73 enum SectionOrder { 74 SHO_INTERP = 1, // .interp 75 SHO_RO_NOTE, // .note.ABI-tag, .note.gnu.build-id 76 SHO_NAMEPOOL, // *.hash, .dynsym, .dynstr 77 SHO_RELOCATION, // .rel.*, .rela.* 78 SHO_REL_PLT, // .rel.plt should come after other .rel.* 79 SHO_INIT, // .init 80 SHO_PLT, // .plt 81 SHO_TEXT, // .text 82 SHO_FINI, // .fini 83 SHO_RO, // .rodata 84 SHO_EHFRAME, // .eh_frame_hdr, .eh_frame 85 SHO_TLS_DATA, // .tdata 86 SHO_TLS_BSS, // .tbss 87 SHO_RELRO_LOCAL, // .data.rel.ro.local 88 SHO_RELRO, // .data.rel.ro, 89 SHO_RELRO_LAST, // for x86 to adjust .got if needed 90 SHO_NON_RELRO_FIRST, // for x86 to adjust .got.plt if needed 91 SHO_DATA, // .data 92 SHO_LARGE_DATA, // .ldata 93 SHO_RW_NOTE, // 94 SHO_SMALL_DATA, // .sdata 95 SHO_SMALL_BSS, // .sbss 96 SHO_BSS, // .bss 97 SHO_LARGE_BSS, // .lbss 98 SHO_UNDEFINED = ~(0U) // default order 99 }; 100 101 protected: 102 GNULDBackend(); 103 104 public: 105 virtual ~GNULDBackend(); 106 107 bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo); 108 bool initObjectReader(MCLinker& pLinker); 109 bool initDynObjReader(MCLinker& pLinker); 110 bool initObjectWriter(MCLinker& pLinker); 111 bool initDynObjWriter(MCLinker& pLinker); 112 113 bool initExecSections(MCLinker& pMCLinker); 114 bool initDynObjSections(MCLinker& pMCLinker); 115 116 bool initStandardSymbols(MCLinker& pLinker); 117 118 GNUArchiveReader *getArchiveReader(); 119 GNUArchiveReader *getArchiveReader() const; 120 121 ELFObjectReader *getObjectReader(); 122 ELFObjectReader *getObjectReader() const; 123 124 ELFDynObjReader *getDynObjReader(); 125 ELFDynObjReader *getDynObjReader() const; 126 127 ELFObjectWriter *getObjectWriter(); 128 ELFObjectWriter *getObjectWriter() const; 129 130 ELFDynObjWriter *getDynObjWriter(); 131 ELFDynObjWriter *getDynObjWriter() const; 132 133 ELFDynObjFileFormat* getDynObjFileFormat(); 134 ELFDynObjFileFormat* getDynObjFileFormat() const; 135 136 ELFExecFileFormat* getExecFileFormat(); 137 ELFExecFileFormat* getExecFileFormat() const; 138 139 size_t sectionStartOffset() const; 140 141 /// The return value of machine() it the same as e_machine in the ELF header*/ 142 virtual uint32_t machine() const = 0; 143 144 /// ELFVersion - the value of e_ident[EI_VERSION] 145 virtual uint8_t ELFVersion() const 146 { return llvm::ELF::EV_CURRENT; } 147 148 /// OSABI - the value of e_ident[EI_OSABI] 149 virtual uint8_t OSABI() const = 0; 150 151 /// ABIVersion - the value of e_ident[EI_ABIVRESION] 152 virtual uint8_t ABIVersion() const = 0; 153 154 /// flags - the value of ElfXX_Ehdr::e_flags 155 virtual uint64_t flags() const = 0; 156 157 /// entry - the symbol name of the entry point 158 virtual const char* entry() const 159 { return "_start"; } 160 161 /// sizeNamePools - compute the size of regular name pools 162 /// In ELF executable files, regular name pools are .symtab, .strtab., 163 /// .dynsym, .dynstr, and .hash 164 virtual void sizeNamePools(const Output& pOutput, 165 const SymbolCategory& pSymbols, 166 const MCLDInfo& pLDInfo); 167 168 /// emitSectionData - emit target-dependent section data 169 virtual uint64_t emitSectionData(const Output& pOutput, 170 const LDSection& pSection, 171 const MCLDInfo& pInfo, 172 MemoryRegion& pRegion) const = 0; 173 174 /// emitRegNamePools - emit regular name pools - .symtab, .strtab 175 virtual void emitRegNamePools(Output& pOutput, 176 SymbolCategory& pSymbols, 177 const Layout& pLayout, 178 const MCLDInfo& pLDInfo); 179 180 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 181 virtual void emitDynNamePools(Output& pOutput, 182 SymbolCategory& pSymbols, 183 const Layout& pLayout, 184 const MCLDInfo& pLDInfo); 185 186 /// getSectionOrder - compute the layout order of the section 187 /// Layout calls this function to get the default order of the pSectHdr. 188 /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder() 189 /// will call getTargetSectionOrder(). 190 /// 191 /// If targets favors certain order for general sections, please override 192 /// this function. 193 /// 194 /// @see getTargetSectionOrder 195 virtual unsigned int getSectionOrder(const Output& pOutput, 196 const LDSection& pSectHdr) const; 197 198 /// getTargetSectionOrder - compute the layout order of target section 199 /// If the target favors certain order for the given gSectHdr, please 200 /// override this function. 201 /// 202 /// By default, this function returns the maximun order, and pSectHdr 203 /// will be the last section to be laid out. 204 virtual unsigned int 205 getTargetSectionOrder(const Output& pOutput, const LDSection& pSectHdr) const 206 { return (unsigned int)-1; } 207 208 /// emitProgramHdrs - emit ELF program headers 209 /// if the target favors other ways to emit program header, please override 210 /// this function 211 virtual void emitProgramHdrs(Output& pOutput); 212 213 /// numOfSegments - return the number of segments 214 /// if the target favors other ways to emit program header, please override 215 /// this function 216 virtual unsigned int numOfSegments() const 217 { return m_ELFSegmentTable.size(); } 218 219 /// pagesize - the page size of the target machine, we set it to 4K here. 220 /// If target favors tht different size of page, please override this function 221 virtual unsigned int pagesize() const 222 { return 0x1000; } 223 224 /// getSymbolIdx - get the symbol index of ouput symbol table 225 size_t getSymbolIdx(LDSymbol* pSymbol) const; 226 227 private: 228 /// createProgramHdrs - base on output sections to create the program headers 229 void createProgramHdrs(LDContext& pContext); 230 231 /// writeELF32ProgramHdrs - write out the ELF32 program headers 232 void writeELF32ProgramHdrs(Output& pOutput); 233 234 /// writeELF64ProgramHdrs - write out the ELF64 program headers 235 void writeELF64ProgramHdrs(Output& pOutput); 236 237 /// getSegmentFlag - give a section flag and return the corresponding segment 238 /// flag 239 inline uint32_t getSegmentFlag(const uint32_t pSectionFlag) 240 { 241 uint32_t flag = llvm::ELF::PF_R; 242 if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE)) 243 flag |= llvm::ELF::PF_W; 244 if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR)) 245 flag |= llvm::ELF::PF_X; 246 return flag; 247 } 248 249 /// preLayout - Backend can do any needed modification before layout 250 void preLayout(const Output& pOutput, 251 const MCLDInfo& pInfo, 252 MCLinker& pLinker); 253 254 /// postLayout -Backend can do any needed modification after layout 255 void postLayout(const Output& pOutput, 256 const MCLDInfo& pInfo, 257 MCLinker& pLinker); 258 259 protected: 260 uint64_t getSymbolSize(const LDSymbol& pSymbol) const; 261 262 uint64_t getSymbolInfo(const LDSymbol& pSymbol) const; 263 264 uint64_t getSymbolValue(const LDSymbol& pSymbol) const; 265 266 uint64_t getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const; 267 268 private: 269 /// preLayout - Backend can do any needed modification before layout 270 virtual void doPreLayout(const Output& pOutput, 271 const MCLDInfo& pInfo, 272 MCLinker& pLinker) = 0; 273 274 /// postLayout -Backend can do any needed modification after layout 275 virtual void doPostLayout(const Output& pOutput, 276 const MCLDInfo& pInfo, 277 MCLinker& pLinker) = 0; 278 279 /// dynamic - the dynamic section of the target machine. 280 virtual ELFDynamic& dynamic() = 0; 281 282 /// dynamic - the dynamic section of the target machine. 283 virtual const ELFDynamic& dynamic() const = 0; 284 285 protected: 286 // ----- readers and writers ----- // 287 GNUArchiveReader* m_pArchiveReader; 288 ELFObjectReader* m_pObjectReader; 289 ELFDynObjReader* m_pDynObjReader; 290 ELFObjectWriter* m_pObjectWriter; 291 ELFDynObjWriter* m_pDynObjWriter; 292 293 // ----- file formats ----- // 294 ELFDynObjFileFormat* m_pDynObjFileFormat; 295 ELFExecFileFormat* m_pExecFileFormat; 296 297 // ----- ELF segment factory ----- // 298 ELFSegmentFactory m_ELFSegmentTable; 299 300 // ----- ELF special sections ----- // 301 302 protected: 303 /// getHashBucketCount - calculate hash bucket count. 304 /// @ref Google gold linker, dynobj.cc:791 305 static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle); 306 307 /// isDynamicSymbol 308 /// @ref Google gold linker: symtab.cc:311 309 static bool isDynamicSymbol(const LDSymbol& pSymbol, const Output& pOutput); 310 311 protected: 312 typedef HashEntry<LDSymbol*, size_t, SymCompare> HashEntryType; 313 typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableType; 314 315 /// m_pSymIndexMap - Map the LDSymbol to its index in the output symbol table 316 HashTableType* m_pSymIndexMap; 317 }; 318 319 } // namespace of mcld 320 321 #endif 322 323