//===- ELFFileFormat.cpp --------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/LD/ELFFileFormat.h> #include <mcld/Object/ObjectBuilder.h> #include <mcld/Target/GNULDBackend.h> #include <llvm/Support/ELF.h> using namespace mcld; ELFFileFormat::ELFFileFormat() : f_pNULLSection(NULL), f_pGOT(NULL), f_pPLT(NULL), f_pRelDyn(NULL), f_pRelPlt(NULL), f_pRelaDyn(NULL), f_pRelaPlt(NULL), f_pComment(NULL), f_pData1(NULL), f_pDebug(NULL), f_pDynamic(NULL), f_pDynStrTab(NULL), f_pDynSymTab(NULL), f_pFini(NULL), f_pFiniArray(NULL), f_pHashTab(NULL), f_pInit(NULL), f_pInitArray(NULL), f_pInterp(NULL), f_pLine(NULL), f_pNote(NULL), f_pPreInitArray(NULL), f_pROData1(NULL), f_pShStrTab(NULL), f_pStrTab(NULL), f_pSymTab(NULL), f_pTBSS(NULL), f_pTData(NULL), f_pCtors(NULL), f_pDataRelRo(NULL), f_pDtors(NULL), f_pEhFrame(NULL), f_pEhFrameHdr(NULL), f_pGCCExceptTable(NULL), f_pGNUVersion(NULL), f_pGNUVersionD(NULL), f_pGNUVersionR(NULL), f_pGOTPLT(NULL), f_pJCR(NULL), f_pNoteABITag(NULL), f_pStab(NULL), f_pStabStr(NULL), f_pStack(NULL), f_pStackNote(NULL), f_pDataRelRoLocal(NULL), f_pGNUHashTab(NULL) { } void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass) { f_pTextSection = pBuilder.CreateSection(".text", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 0x1); f_pNULLSection = pBuilder.CreateSection("", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0); f_pReadOnlySection = pBuilder.CreateSection(".rodata", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC, 0x1); f_pBSSSection = pBuilder.CreateSection(".bss", LDFileFormat::BSS, llvm::ELF::SHT_NOBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pComment = pBuilder.CreateSection(".comment", LDFileFormat::MetaData, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); f_pDataSection = pBuilder.CreateSection(".data", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pData1 = pBuilder.CreateSection(".data1", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pDebug = pBuilder.CreateSection(".debug", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); f_pInit = pBuilder.CreateSection(".init", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 0x1); f_pInitArray = pBuilder.CreateSection(".init_array", LDFileFormat::Regular, llvm::ELF::SHT_INIT_ARRAY, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pFini = pBuilder.CreateSection(".fini", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR, 0x1); f_pFiniArray = pBuilder.CreateSection(".fini_array", LDFileFormat::Regular, llvm::ELF::SHT_FINI_ARRAY, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pLine = pBuilder.CreateSection(".line", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); f_pPreInitArray = pBuilder.CreateSection(".preinit_array", LDFileFormat::Regular, llvm::ELF::SHT_PREINIT_ARRAY, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); // the definition of SHF_XXX attributes of rodata in Linux Standard Base // conflicts with System V standard. We follow System V standard. f_pROData1 = pBuilder.CreateSection(".rodata1", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC, 0x1); f_pShStrTab = pBuilder.CreateSection(".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1); // In ELF Spec Book I, p1-16. If symbol table and string table are in // loadable segments, set the attribute to SHF_ALLOC bit. But in the // real world, this bit always turn off. f_pSymTab = pBuilder.CreateSection(".symtab", LDFileFormat::NamePool, llvm::ELF::SHT_SYMTAB, 0x0, pBitClass / 8); f_pStrTab = pBuilder.CreateSection(".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1); f_pTBSS = pBuilder.CreateSection(".tbss", LDFileFormat::BSS, llvm::ELF::SHT_NOBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS, 0x1); f_pTData = pBuilder.CreateSection(".tdata", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS, 0x1); /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. f_pCtors = pBuilder.CreateSection(".ctors", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pDataRelRo = pBuilder.CreateSection(".data.rel.ro", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pDtors = pBuilder.CreateSection(".dtors", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pEhFrame = pBuilder.CreateSection(".eh_frame", LDFileFormat::EhFrame, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC, 0x4); f_pGCCExceptTable = pBuilder.CreateSection(".gcc_except_table", LDFileFormat::GCCExceptTable, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC, 0x4); f_pGNUVersion = pBuilder.CreateSection(".gnu.version", LDFileFormat::Version, llvm::ELF::SHT_GNU_versym, llvm::ELF::SHF_ALLOC, 0x1); f_pGNUVersionD = pBuilder.CreateSection(".gnu.version_d", LDFileFormat::Version, llvm::ELF::SHT_GNU_verdef, llvm::ELF::SHF_ALLOC, 0x1); f_pGNUVersionR = pBuilder.CreateSection(".gnu.version_r", LDFileFormat::Version, llvm::ELF::SHT_GNU_verneed, llvm::ELF::SHF_ALLOC, 0x1); f_pJCR = pBuilder.CreateSection(".jcr", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); f_pStab = pBuilder.CreateSection(".stab", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); f_pStabStr = pBuilder.CreateSection(".stabstr", LDFileFormat::Debug, llvm::ELF::SHT_STRTAB, 0x0, 0x1); f_pStackNote = pBuilder.CreateSection(".note.GNU-stack", LDFileFormat::StackNote, llvm::ELF::SHT_PROGBITS, 0x0, 0x1); /// @ref GCC convention, see http://www.airs.com/blog/archives/189 f_pDataRelRoLocal = pBuilder.CreateSection(".data.rel.ro.local", LDFileFormat::Regular, llvm::ELF::SHT_PROGBITS, llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 0x1); /// Initialize format dependent sections. (sections for executable and shared /// objects) initObjectFormat(pBuilder, pBitClass); }