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