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 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 void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, 67 unsigned int pBitClass) { 68 f_pTextSection = 69 pBuilder.CreateSection(".text", 70 LDFileFormat::TEXT, 71 llvm::ELF::SHT_PROGBITS, 72 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 73 0x1); 74 f_pNULLSection = 75 pBuilder.CreateSection("", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0); 76 f_pReadOnlySection = pBuilder.CreateSection(".rodata", 77 LDFileFormat::TEXT, 78 llvm::ELF::SHT_PROGBITS, 79 llvm::ELF::SHF_ALLOC, 80 0x1); 81 82 f_pBSSSection = 83 pBuilder.CreateSection(".bss", 84 LDFileFormat::BSS, 85 llvm::ELF::SHT_NOBITS, 86 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 87 0x1); 88 f_pComment = pBuilder.CreateSection( 89 ".comment", LDFileFormat::MetaData, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); 90 f_pDataSection = 91 pBuilder.CreateSection(".data", 92 LDFileFormat::DATA, 93 llvm::ELF::SHT_PROGBITS, 94 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 95 0x1); 96 f_pData1 = pBuilder.CreateSection(".data1", 97 LDFileFormat::DATA, 98 llvm::ELF::SHT_PROGBITS, 99 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 100 0x1); 101 f_pDebug = pBuilder.CreateSection( 102 ".debug", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); 103 f_pInit = 104 pBuilder.CreateSection(".init", 105 LDFileFormat::TEXT, 106 llvm::ELF::SHT_PROGBITS, 107 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 108 0x1); 109 f_pInitArray = 110 pBuilder.CreateSection(".init_array", 111 LDFileFormat::DATA, 112 llvm::ELF::SHT_INIT_ARRAY, 113 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 114 0x1); 115 f_pFini = 116 pBuilder.CreateSection(".fini", 117 LDFileFormat::TEXT, 118 llvm::ELF::SHT_PROGBITS, 119 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 120 0x1); 121 f_pFiniArray = 122 pBuilder.CreateSection(".fini_array", 123 LDFileFormat::DATA, 124 llvm::ELF::SHT_FINI_ARRAY, 125 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 126 0x1); 127 f_pLine = pBuilder.CreateSection( 128 ".line", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); 129 f_pPreInitArray = 130 pBuilder.CreateSection(".preinit_array", 131 LDFileFormat::DATA, 132 llvm::ELF::SHT_PREINIT_ARRAY, 133 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 134 0x1); 135 // the definition of SHF_XXX attributes of rodata in Linux Standard Base 136 // conflicts with System V standard. We follow System V standard. 137 f_pROData1 = pBuilder.CreateSection(".rodata1", 138 LDFileFormat::TEXT, 139 llvm::ELF::SHT_PROGBITS, 140 llvm::ELF::SHF_ALLOC, 141 0x1); 142 f_pShStrTab = pBuilder.CreateSection( 143 ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1); 144 // In ELF Spec Book I, p1-16. If symbol table and string table are in 145 // loadable segments, set the attribute to SHF_ALLOC bit. But in the 146 // real world, this bit always turn off. 147 f_pSymTab = pBuilder.CreateSection(".symtab", 148 LDFileFormat::NamePool, 149 llvm::ELF::SHT_SYMTAB, 150 0x0, 151 pBitClass / 8); 152 153 f_pStrTab = pBuilder.CreateSection( 154 ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1); 155 f_pTBSS = pBuilder.CreateSection( 156 ".tbss", 157 LDFileFormat::BSS, 158 llvm::ELF::SHT_NOBITS, 159 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS, 160 0x1); 161 f_pTData = pBuilder.CreateSection( 162 ".tdata", 163 LDFileFormat::DATA, 164 llvm::ELF::SHT_PROGBITS, 165 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS, 166 0x1); 167 168 /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. 169 f_pCtors = pBuilder.CreateSection(".ctors", 170 LDFileFormat::DATA, 171 llvm::ELF::SHT_PROGBITS, 172 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 173 0x1); 174 f_pDataRelRo = 175 pBuilder.CreateSection(".data.rel.ro", 176 LDFileFormat::DATA, 177 llvm::ELF::SHT_PROGBITS, 178 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 179 0x1); 180 f_pDtors = pBuilder.CreateSection(".dtors", 181 LDFileFormat::DATA, 182 llvm::ELF::SHT_PROGBITS, 183 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 184 0x1); 185 f_pEhFrame = pBuilder.CreateSection(".eh_frame", 186 LDFileFormat::EhFrame, 187 llvm::ELF::SHT_PROGBITS, 188 llvm::ELF::SHF_ALLOC, 189 0x4); 190 f_pGCCExceptTable = pBuilder.CreateSection(".gcc_except_table", 191 LDFileFormat::GCCExceptTable, 192 llvm::ELF::SHT_PROGBITS, 193 llvm::ELF::SHF_ALLOC, 194 0x4); 195 f_pGNUVersion = pBuilder.CreateSection(".gnu.version", 196 LDFileFormat::Version, 197 llvm::ELF::SHT_GNU_versym, 198 llvm::ELF::SHF_ALLOC, 199 0x1); 200 f_pGNUVersionD = pBuilder.CreateSection(".gnu.version_d", 201 LDFileFormat::Version, 202 llvm::ELF::SHT_GNU_verdef, 203 llvm::ELF::SHF_ALLOC, 204 0x1); 205 f_pGNUVersionR = pBuilder.CreateSection(".gnu.version_r", 206 LDFileFormat::Version, 207 llvm::ELF::SHT_GNU_verneed, 208 llvm::ELF::SHF_ALLOC, 209 0x1); 210 f_pJCR = pBuilder.CreateSection(".jcr", 211 LDFileFormat::DATA, 212 llvm::ELF::SHT_PROGBITS, 213 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 214 0x1); 215 f_pStab = pBuilder.CreateSection( 216 ".stab", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); 217 f_pStabStr = pBuilder.CreateSection( 218 ".stabstr", LDFileFormat::Debug, llvm::ELF::SHT_STRTAB, 0x0, 0x1); 219 f_pStackNote = pBuilder.CreateSection(".note.GNU-stack", 220 LDFileFormat::StackNote, 221 llvm::ELF::SHT_PROGBITS, 222 0x0, 223 0x1); 224 225 /// @ref GCC convention, see http://www.airs.com/blog/archives/189 226 f_pDataRelRoLocal = 227 pBuilder.CreateSection(".data.rel.ro.local", 228 LDFileFormat::DATA, 229 llvm::ELF::SHT_PROGBITS, 230 llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 231 0x1); 232 /// Initialize format dependent sections. (sections for executable and shared 233 /// objects) 234 initObjectFormat(pBuilder, pBitClass); 235 } 236 237 } // namespace mcld 238