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