1 //===- ELFFileFormat.cpp --------------------------------------------------===// 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 #include <mcld/LD/ELFFileFormat.h> 10 #include <mcld/MC/MCLinker.h> 11 #include <mcld/MC/MCLDFile.h> 12 #include <llvm/Support/ELF.h> 13 #include <mcld/Target/GNULDBackend.h> 14 15 using namespace mcld; 16 17 ELFFileFormat::ELFFileFormat(GNULDBackend& pBackend) 18 : f_Backend(pBackend), 19 f_pNULLSection(NULL), 20 f_pGOT(NULL), 21 f_pPLT(NULL), 22 f_pRelDyn(NULL), 23 f_pRelPlt(NULL), 24 f_pRelaDyn(NULL), 25 f_pRelaPlt(NULL), 26 f_pComment(NULL), 27 f_pData1(NULL), 28 f_pDebug(NULL), 29 f_pDynamic(NULL), 30 f_pDynStrTab(NULL), 31 f_pDynSymTab(NULL), 32 f_pFini(NULL), 33 f_pFiniArray(NULL), 34 f_pHashTab(NULL), 35 f_pInit(NULL), 36 f_pInitArray(NULL), 37 f_pInterp(NULL), 38 f_pLine(NULL), 39 f_pNote(NULL), 40 f_pPreInitArray(NULL), 41 f_pROData1(NULL), 42 f_pShStrTab(NULL), 43 f_pStrTab(NULL), 44 f_pSymTab(NULL), 45 f_pTBSS(NULL), 46 f_pTData(NULL), 47 f_pCtors(NULL), 48 f_pDataRelRo(NULL), 49 f_pDtors(NULL), 50 f_pEhFrame(NULL), 51 f_pEhFrameHdr(NULL), 52 f_pGCCExceptTable(NULL), 53 f_pGNUVersion(NULL), 54 f_pGNUVersionD(NULL), 55 f_pGNUVersionR(NULL), 56 f_pGOTPLT(NULL), 57 f_pJCR(NULL), 58 f_pNoteABITag(NULL), 59 f_pStab(NULL), 60 f_pStabStr(NULL) { 61 62 } 63 64 ELFFileFormat::~ELFFileFormat() 65 { 66 } 67 68 void ELFFileFormat::initObjectFormat(MCLinker& pLinker) 69 { 70 f_pTextSection = &pLinker.getOrCreateOutputSectHdr(".text", 71 LDFileFormat::Regular, 72 llvm::ELF::SHT_PROGBITS, 73 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 74 0x1); 75 f_pNULLSection = &pLinker.getOrCreateOutputSectHdr("", 76 LDFileFormat::Null, 77 llvm::ELF::SHT_NULL, 78 0x0); 79 f_pReadOnlySection = &pLinker.getOrCreateOutputSectHdr(".rodata", 80 LDFileFormat::Regular, 81 llvm::ELF::SHT_PROGBITS, 82 llvm::ELF::SHF_ALLOC, 83 0x1); 84 85 f_pBSSSection = &pLinker.getOrCreateOutputSectHdr(".bss", 86 LDFileFormat::BSS, 87 llvm::ELF::SHT_NOBITS, 88 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 89 0x1); 90 f_pComment = &pLinker.getOrCreateOutputSectHdr(".comment", 91 LDFileFormat::MetaData, 92 llvm::ELF::SHT_PROGBITS, 93 0x0, 94 0x1); 95 f_pDataSection = &pLinker.getOrCreateOutputSectHdr(".data", 96 LDFileFormat::Regular, 97 llvm::ELF::SHT_PROGBITS, 98 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 99 0x1); 100 f_pData1 = &pLinker.getOrCreateOutputSectHdr(".data1", 101 LDFileFormat::Regular, 102 llvm::ELF::SHT_PROGBITS, 103 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 104 0x1); 105 f_pDebug = &pLinker.getOrCreateOutputSectHdr(".debug", 106 LDFileFormat::Debug, 107 llvm::ELF::SHT_PROGBITS, 108 0x0, 109 0x1); 110 f_pInit = &pLinker.getOrCreateOutputSectHdr(".init", 111 LDFileFormat::Regular, 112 llvm::ELF::SHT_PROGBITS, 113 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 114 0x1); 115 f_pInitArray = &pLinker.getOrCreateOutputSectHdr(".init_array", 116 LDFileFormat::Regular, 117 llvm::ELF::SHT_INIT_ARRAY, 118 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 119 0x1); 120 f_pFini = &pLinker.getOrCreateOutputSectHdr(".fini", 121 LDFileFormat::Regular, 122 llvm::ELF::SHT_PROGBITS, 123 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 124 0x1); 125 f_pFiniArray = &pLinker.getOrCreateOutputSectHdr(".fini_array", 126 LDFileFormat::Regular, 127 llvm::ELF::SHT_FINI_ARRAY, 128 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 129 0x1); 130 f_pLine = &pLinker.getOrCreateOutputSectHdr(".line", 131 LDFileFormat::Debug, 132 llvm::ELF::SHT_PROGBITS, 133 0x0, 134 0x1); 135 f_pPreInitArray = &pLinker.getOrCreateOutputSectHdr(".preinit_array", 136 LDFileFormat::Regular, 137 llvm::ELF::SHT_PREINIT_ARRAY, 138 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 139 0x1); 140 // the definition of SHF_XXX attributes of rodata in Linux Standard Base 141 // conflicts with System V standard. We follow System V standard. 142 f_pROData1 = &pLinker.getOrCreateOutputSectHdr(".rodata1", 143 LDFileFormat::Regular, 144 llvm::ELF::SHT_PROGBITS, 145 llvm::ELF::SHF_ALLOC, 146 0x1); 147 f_pShStrTab = &pLinker.getOrCreateOutputSectHdr(".shstrtab", 148 LDFileFormat::NamePool, 149 llvm::ELF::SHT_STRTAB, 150 0x0, 151 0x1); 152 // In ELF Spec Book I, p1-16. If symbol table and string table are in 153 // loadable segments, set the attribute to SHF_ALLOC bit. But in the 154 // real world, this bit always turn off. 155 f_pSymTab = &pLinker.getOrCreateOutputSectHdr(".symtab", 156 LDFileFormat::NamePool, 157 llvm::ELF::SHT_SYMTAB, 158 0x0, 159 f_Backend.bitclass() / 8); 160 f_pStrTab = &pLinker.getOrCreateOutputSectHdr(".strtab", 161 LDFileFormat::NamePool, 162 llvm::ELF::SHT_STRTAB, 163 0x0, 164 0x1); 165 f_pTBSS = &pLinker.getOrCreateOutputSectHdr(".tbss", 166 LDFileFormat::BSS, 167 llvm::ELF::SHT_NOBITS, 168 llvm::ELF::SHF_ALLOC | 169 llvm::ELF::SHF_WRITE | 170 llvm::ELF::SHF_TLS, 171 0x1); 172 f_pTData = &pLinker.getOrCreateOutputSectHdr(".tdata", 173 LDFileFormat::Regular, 174 llvm::ELF::SHT_PROGBITS, 175 llvm::ELF::SHF_ALLOC | 176 llvm::ELF::SHF_WRITE | 177 llvm::ELF::SHF_TLS, 178 0x1); 179 180 /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. 181 f_pCtors = &pLinker.getOrCreateOutputSectHdr(".ctor", 182 LDFileFormat::Regular, 183 llvm::ELF::SHT_PROGBITS, 184 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 185 0x1); 186 f_pDataRelRo = &pLinker.getOrCreateOutputSectHdr(".data.rel.ro", 187 LDFileFormat::Regular, 188 llvm::ELF::SHT_PROGBITS, 189 llvm::ELF::SHF_ALLOC, 190 0x1); 191 f_pDtors = &pLinker.getOrCreateOutputSectHdr(".dtors", 192 LDFileFormat::Regular, 193 llvm::ELF::SHT_PROGBITS, 194 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 195 0x1); 196 f_pEhFrame = &pLinker.getOrCreateOutputSectHdr(".eh_frame", 197 LDFileFormat::Exception, 198 llvm::ELF::SHT_PROGBITS, 199 llvm::ELF::SHF_ALLOC, 200 0x1); 201 f_pEhFrameHdr = &pLinker.getOrCreateOutputSectHdr(".eh_frame_hdr", 202 LDFileFormat::Exception, 203 llvm::ELF::SHT_PROGBITS, 204 llvm::ELF::SHF_ALLOC, 205 0x1); 206 f_pGCCExceptTable = &pLinker.getOrCreateOutputSectHdr(".gcc_except_table", 207 LDFileFormat::Exception, 208 llvm::ELF::SHT_PROGBITS, 209 llvm::ELF::SHF_ALLOC, 210 0x1); 211 f_pGNUVersion = &pLinker.getOrCreateOutputSectHdr(".gnu.version", 212 LDFileFormat::Version, 213 llvm::ELF::SHT_GNU_versym, 214 llvm::ELF::SHF_ALLOC, 215 0x1); 216 f_pGNUVersionD = &pLinker.getOrCreateOutputSectHdr(".gnu.version_d", 217 LDFileFormat::Version, 218 llvm::ELF::SHT_GNU_verdef, 219 llvm::ELF::SHF_ALLOC, 220 0x1); 221 f_pGNUVersionR = &pLinker.getOrCreateOutputSectHdr(".gnu.version_r", 222 LDFileFormat::Version, 223 llvm::ELF::SHT_GNU_verneed, 224 llvm::ELF::SHF_ALLOC, 225 0x1); 226 f_pJCR = &pLinker.getOrCreateOutputSectHdr(".jcr", 227 LDFileFormat::Regular, 228 llvm::ELF::SHT_PROGBITS, 229 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 230 0x1); 231 f_pStab = &pLinker.getOrCreateOutputSectHdr(".stab", 232 LDFileFormat::Debug, 233 llvm::ELF::SHT_PROGBITS, 234 0x0, 235 0x1); 236 f_pStabStr = &pLinker.getOrCreateOutputSectHdr(".stabstr", 237 LDFileFormat::Debug, 238 llvm::ELF::SHT_STRTAB, 239 0x0, 240 0x1); 241 } 242 243