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