//===- 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);
}