| //===- LDFileFormat.h -----------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef MCLD_ELF_FILE_FORMAT_H |
| #define MCLD_ELF_FILE_FORMAT_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| #include <mcld/LD/LDFileFormat.h> |
| #include <mcld/LD/LDSection.h> |
| |
| namespace mcld { |
| |
| class ObjectBuilder; |
| |
| /** \class ELFFileFormat |
| * \brief ELFFileFormat describes the common file formats in ELF. |
| * LDFileFormats control the formats of the output file. |
| * |
| * @ref "Object Files," Ch. 4, in System V Application Binary Interface, |
| * Fourth Edition. |
| * |
| * @ref "Object Format," Ch. 10, in ISO/IEC 23360 Part 1:2010(E), Linux |
| * Standard Base Core Specification 4.1. |
| */ |
| class ELFFileFormat : public LDFileFormat |
| { |
| private: |
| /// initObjectFormat - initialize sections that are dependent on object |
| /// formats. (executable, shared objects or relocatable objects). |
| virtual void |
| initObjectFormat(ObjectBuilder& pBuilder, unsigned int pBitClass) = 0; |
| |
| public: |
| ELFFileFormat(); |
| |
| void initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass); |
| |
| // ----- capacity ----- // |
| /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition. |
| bool hasNULLSection() const |
| { return (NULL != f_pNULLSection) && (0 != f_pNULLSection->size()); } |
| |
| bool hasGOT() const |
| { return (NULL != f_pGOT) && (0 != f_pGOT->size()); } |
| |
| bool hasPLT() const |
| { return (NULL != f_pPLT) && (0 != f_pPLT->size()); } |
| |
| bool hasRelDyn() const |
| { return (NULL != f_pRelDyn) && (0 != f_pRelDyn->size()); } |
| |
| bool hasRelPlt() const |
| { return (NULL != f_pRelPlt) && (0 != f_pRelPlt->size()); } |
| |
| bool hasRelaDyn() const |
| { return (NULL != f_pRelaDyn) && (0 != f_pRelaDyn->size()); } |
| |
| bool hasRelaPlt() const |
| { return (NULL != f_pRelaPlt) && (0 != f_pRelaPlt->size()); } |
| |
| /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21. |
| bool hasComment() const |
| { return (NULL != f_pComment) && (0 != f_pComment->size()); } |
| |
| bool hasData1() const |
| { return (NULL != f_pData1) && (0 != f_pData1->size()); } |
| |
| bool hasDebug() const |
| { return (NULL != f_pDebug) && (0 != f_pDebug->size()); } |
| |
| bool hasDynamic() const |
| { return (NULL != f_pDynamic) && (0 != f_pDynamic->size()); } |
| |
| bool hasDynStrTab() const |
| { return (NULL != f_pDynStrTab) && (0 != f_pDynStrTab->size()); } |
| |
| bool hasDynSymTab() const |
| { return (NULL != f_pDynSymTab) && (0 != f_pDynSymTab->size()); } |
| |
| bool hasFini() const |
| { return (NULL != f_pFini) && (0 != f_pFini->size()); } |
| |
| bool hasFiniArray() const |
| { return (NULL != f_pFiniArray) && (0 != f_pFiniArray->size()); } |
| |
| bool hasHashTab() const |
| { return (NULL != f_pHashTab) && (0 != f_pHashTab->size()); } |
| |
| bool hasInit() const |
| { return (NULL != f_pInit) && (0 != f_pInit->size()); } |
| |
| bool hasInitArray() const |
| { return (NULL != f_pInitArray) && (0 != f_pInitArray->size()); } |
| |
| bool hasInterp() const |
| { return (NULL != f_pInterp) && (0 != f_pInterp->size()); } |
| |
| bool hasLine() const |
| { return (NULL != f_pLine) && (0 != f_pLine->size()); } |
| |
| bool hasNote() const |
| { return (NULL != f_pNote) && (0 != f_pNote->size()); } |
| |
| bool hasPreInitArray() const |
| { return (NULL != f_pPreInitArray) && (0 != f_pPreInitArray->size()); } |
| |
| bool hasROData1() const |
| { return (NULL != f_pROData1) && (0 != f_pROData1->size()); } |
| |
| bool hasShStrTab() const |
| { return (NULL != f_pShStrTab) && (0 != f_pShStrTab->size()); } |
| |
| bool hasStrTab() const |
| { return (NULL != f_pStrTab) && (0 != f_pStrTab->size()); } |
| |
| bool hasSymTab() const |
| { return (NULL != f_pSymTab) && (0 != f_pSymTab->size()); } |
| |
| bool hasTBSS() const |
| { return (NULL != f_pTBSS) && (0 != f_pTBSS->size()); } |
| |
| bool hasTData() const |
| { return (NULL != f_pTData) && (0 != f_pTData->size()); } |
| |
| /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. |
| bool hasCtors() const |
| { return (NULL != f_pCtors) && (0 != f_pCtors->size()); } |
| |
| bool hasDataRelRo() const |
| { return (NULL != f_pDataRelRo) && (0 != f_pDataRelRo->size()); } |
| |
| bool hasDtors() const |
| { return (NULL != f_pDtors) && (0 != f_pDtors->size()); } |
| |
| bool hasEhFrame() const |
| { return (NULL != f_pEhFrame) && (0 != f_pEhFrame->size()); } |
| |
| bool hasEhFrameHdr() const |
| { return (NULL != f_pEhFrameHdr) && (0 != f_pEhFrameHdr->size()); } |
| |
| bool hasGCCExceptTable() const |
| { return (NULL != f_pGCCExceptTable) && (0 != f_pGCCExceptTable->size()); } |
| |
| bool hasGNUVersion() const |
| { return (NULL != f_pGNUVersion) && (0 != f_pGNUVersion->size()); } |
| |
| bool hasGNUVersionD() const |
| { return (NULL != f_pGNUVersionD) && (0 != f_pGNUVersionD->size()); } |
| |
| bool hasGNUVersionR() const |
| { return (NULL != f_pGNUVersionR) && (0 != f_pGNUVersionR->size()); } |
| |
| bool hasGOTPLT() const |
| { return (NULL != f_pGOTPLT) && (0 != f_pGOTPLT->size()); } |
| |
| bool hasJCR() const |
| { return (NULL != f_pJCR) && (0 != f_pJCR->size()); } |
| |
| bool hasNoteABITag() const |
| { return (NULL != f_pNoteABITag) && (0 != f_pNoteABITag->size()); } |
| |
| bool hasStab() const |
| { return (NULL != f_pStab) && (0 != f_pStab->size()); } |
| |
| bool hasStabStr() const |
| { return (NULL != f_pStabStr) && (0 != f_pStabStr->size()); } |
| |
| bool hasStack() const |
| { return (NULL != f_pStack) && (0 != f_pStack->size()); } |
| |
| bool hasStackNote() const |
| { return (NULL != f_pStackNote); } |
| |
| bool hasDataRelRoLocal() const |
| { return (NULL != f_pDataRelRoLocal) && (0 != f_pDataRelRoLocal->size()); } |
| |
| // ----- access functions ----- // |
| /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition. |
| LDSection& getNULLSection() { |
| assert(NULL != f_pNULLSection); |
| return *f_pNULLSection; |
| } |
| |
| const LDSection& getNULLSection() const { |
| assert(NULL != f_pNULLSection); |
| return *f_pNULLSection; |
| } |
| |
| LDSection& getGOT() { |
| assert(NULL != f_pGOT); |
| return *f_pGOT; |
| } |
| |
| const LDSection& getGOT() const { |
| assert(NULL != f_pGOT); |
| return *f_pGOT; |
| } |
| |
| LDSection& getPLT() { |
| assert(NULL != f_pPLT); |
| return *f_pPLT; |
| } |
| |
| const LDSection& getPLT() const { |
| assert(NULL != f_pPLT); |
| return *f_pPLT; |
| } |
| |
| LDSection& getRelDyn() { |
| assert(NULL != f_pRelDyn); |
| return *f_pRelDyn; |
| } |
| |
| const LDSection& getRelDyn() const { |
| assert(NULL != f_pRelDyn); |
| return *f_pRelDyn; |
| } |
| |
| LDSection& getRelPlt() { |
| assert(NULL != f_pRelPlt); |
| return *f_pRelPlt; |
| } |
| |
| const LDSection& getRelPlt() const { |
| assert(NULL != f_pRelPlt); |
| return *f_pRelPlt; |
| } |
| |
| LDSection& getRelaDyn() { |
| assert(NULL != f_pRelaDyn); |
| return *f_pRelaDyn; |
| } |
| |
| const LDSection& getRelaDyn() const { |
| assert(NULL != f_pRelaDyn); |
| return *f_pRelaDyn; |
| } |
| |
| LDSection& getRelaPlt() { |
| assert(NULL != f_pRelaPlt); |
| return *f_pRelaPlt; |
| } |
| |
| const LDSection& getRelaPlt() const { |
| assert(NULL != f_pRelaPlt); |
| return *f_pRelaPlt; |
| } |
| |
| LDSection& getComment() { |
| assert(NULL != f_pComment); |
| return *f_pComment; |
| } |
| |
| /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21. |
| const LDSection& getComment() const { |
| assert(NULL != f_pComment); |
| return *f_pComment; |
| } |
| |
| LDSection& getData1() { |
| assert(NULL != f_pData1); |
| return *f_pData1; |
| } |
| |
| const LDSection& getData1() const { |
| assert(NULL != f_pData1); |
| return *f_pData1; |
| } |
| |
| LDSection& getDebug() { |
| assert(NULL != f_pDebug); |
| return *f_pDebug; |
| } |
| |
| const LDSection& getDebug() const { |
| assert(NULL != f_pDebug); |
| return *f_pDebug; |
| } |
| |
| LDSection& getDynamic() { |
| assert(NULL != f_pDynamic); |
| return *f_pDynamic; |
| } |
| |
| const LDSection& getDynamic() const { |
| assert(NULL != f_pDynamic); |
| return *f_pDynamic; |
| } |
| |
| LDSection& getDynStrTab() { |
| assert(NULL != f_pDynStrTab); |
| return *f_pDynStrTab; |
| } |
| |
| const LDSection& getDynStrTab() const { |
| assert(NULL != f_pDynStrTab); |
| return *f_pDynStrTab; |
| } |
| |
| LDSection& getDynSymTab() { |
| assert(NULL != f_pDynSymTab); |
| return *f_pDynSymTab; |
| } |
| |
| const LDSection& getDynSymTab() const { |
| assert(NULL != f_pDynSymTab); |
| return *f_pDynSymTab; |
| } |
| |
| LDSection& getFini() { |
| assert(NULL != f_pFini); |
| return *f_pFini; |
| } |
| |
| const LDSection& getFini() const { |
| assert(NULL != f_pFini); |
| return *f_pFini; |
| } |
| |
| LDSection& getFiniArray() { |
| assert(NULL != f_pFiniArray); |
| return *f_pFiniArray; |
| } |
| |
| const LDSection& getFiniArray() const { |
| assert(NULL != f_pFiniArray); |
| return *f_pFiniArray; |
| } |
| |
| LDSection& getHashTab() { |
| assert(NULL != f_pHashTab); |
| return *f_pHashTab; |
| } |
| |
| const LDSection& getHashTab() const { |
| assert(NULL != f_pHashTab); |
| return *f_pHashTab; |
| } |
| |
| LDSection& getInit() { |
| assert(NULL != f_pInit); |
| return *f_pInit; |
| } |
| |
| const LDSection& getInit() const { |
| assert(NULL != f_pInit); |
| return *f_pInit; |
| } |
| |
| LDSection& getInitArray() { |
| assert(NULL != f_pInitArray); |
| return *f_pInitArray; |
| } |
| |
| const LDSection& getInitArray() const { |
| assert(NULL != f_pInitArray); |
| return *f_pInitArray; |
| } |
| |
| LDSection& getInterp() { |
| assert(NULL != f_pInterp); |
| return *f_pInterp; |
| } |
| |
| const LDSection& getInterp() const { |
| assert(NULL != f_pInterp); |
| return *f_pInterp; |
| } |
| |
| LDSection& getLine() { |
| assert(NULL != f_pLine); |
| return *f_pLine; |
| } |
| |
| const LDSection& getLine() const { |
| assert(NULL != f_pLine); |
| return *f_pLine; |
| } |
| |
| LDSection& getNote() { |
| assert(NULL != f_pNote); |
| return *f_pNote; |
| } |
| |
| const LDSection& getNote() const { |
| assert(NULL != f_pNote); |
| return *f_pNote; |
| } |
| |
| LDSection& getPreInitArray() { |
| assert(NULL != f_pPreInitArray); |
| return *f_pPreInitArray; |
| } |
| |
| const LDSection& getPreInitArray() const { |
| assert(NULL != f_pPreInitArray); |
| return *f_pPreInitArray; |
| } |
| |
| LDSection& getROData1() { |
| assert(NULL != f_pROData1); |
| return *f_pROData1; |
| } |
| |
| const LDSection& getROData1() const { |
| assert(NULL != f_pROData1); |
| return *f_pROData1; |
| } |
| |
| LDSection& getShStrTab() { |
| assert(NULL != f_pShStrTab); |
| return *f_pShStrTab; |
| } |
| |
| const LDSection& getShStrTab() const { |
| assert(NULL != f_pShStrTab); |
| return *f_pShStrTab; |
| } |
| |
| LDSection& getStrTab() { |
| assert(NULL != f_pStrTab); |
| return *f_pStrTab; |
| } |
| |
| const LDSection& getStrTab() const { |
| assert(NULL != f_pStrTab); |
| return *f_pStrTab; |
| } |
| |
| LDSection& getSymTab() { |
| assert(NULL != f_pSymTab); |
| return *f_pSymTab; |
| } |
| |
| const LDSection& getSymTab() const { |
| assert(NULL != f_pSymTab); |
| return *f_pSymTab; |
| } |
| |
| LDSection& getTBSS() { |
| assert(NULL != f_pTBSS); |
| return *f_pTBSS; |
| } |
| |
| const LDSection& getTBSS() const { |
| assert(NULL != f_pTBSS); |
| return *f_pTBSS; |
| } |
| |
| LDSection& getTData() { |
| assert(NULL != f_pTData); |
| return *f_pTData; |
| } |
| |
| const LDSection& getTData() const { |
| assert(NULL != f_pTData); |
| return *f_pTData; |
| } |
| |
| /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. |
| LDSection& getCtors() { |
| assert(NULL != f_pCtors); |
| return *f_pCtors; |
| } |
| |
| const LDSection& getCtors() const { |
| assert(NULL != f_pCtors); |
| return *f_pCtors; |
| } |
| |
| LDSection& getDataRelRo() { |
| assert(NULL != f_pDataRelRo); |
| return *f_pDataRelRo; |
| } |
| |
| const LDSection& getDataRelRo() const { |
| assert(NULL != f_pDataRelRo); |
| return *f_pDataRelRo; |
| } |
| |
| LDSection& getDtors() { |
| assert(NULL != f_pDtors); |
| return *f_pDtors; |
| } |
| |
| const LDSection& getDtors() const { |
| assert(NULL != f_pDtors); |
| return *f_pDtors; |
| } |
| |
| LDSection& getEhFrame() { |
| assert(NULL != f_pEhFrame); |
| return *f_pEhFrame; |
| } |
| |
| const LDSection& getEhFrame() const { |
| assert(NULL != f_pEhFrame); |
| return *f_pEhFrame; |
| } |
| |
| LDSection& getEhFrameHdr() { |
| assert(NULL != f_pEhFrameHdr); |
| return *f_pEhFrameHdr; |
| } |
| |
| const LDSection& getEhFrameHdr() const { |
| assert(NULL != f_pEhFrameHdr); |
| return *f_pEhFrameHdr; |
| } |
| |
| LDSection& getGCCExceptTable() { |
| assert(NULL != f_pGCCExceptTable); |
| return *f_pGCCExceptTable; |
| } |
| |
| const LDSection& getGCCExceptTable() const { |
| assert(NULL != f_pGCCExceptTable); |
| return *f_pGCCExceptTable; |
| } |
| |
| LDSection& getGNUVersion() { |
| assert(NULL != f_pGNUVersion); |
| return *f_pGNUVersion; |
| } |
| |
| const LDSection& getGNUVersion() const { |
| assert(NULL != f_pGNUVersion); |
| return *f_pGNUVersion; |
| } |
| |
| LDSection& getGNUVersionD() { |
| assert(NULL != f_pGNUVersionD); |
| return *f_pGNUVersionD; |
| } |
| |
| const LDSection& getGNUVersionD() const { |
| assert(NULL != f_pGNUVersionD); |
| return *f_pGNUVersionD; |
| } |
| |
| LDSection& getGNUVersionR() { |
| assert(NULL != f_pGNUVersionR); |
| return *f_pGNUVersionR; |
| } |
| |
| const LDSection& getGNUVersionR() const { |
| assert(NULL != f_pGNUVersionR); |
| return *f_pGNUVersionR; |
| } |
| |
| LDSection& getGOTPLT() { |
| assert(NULL != f_pGOTPLT); |
| return *f_pGOTPLT; |
| } |
| |
| const LDSection& getGOTPLT() const { |
| assert(NULL != f_pGOTPLT); |
| return *f_pGOTPLT; |
| } |
| |
| LDSection& getJCR() { |
| assert(NULL != f_pJCR); |
| return *f_pJCR; |
| } |
| |
| const LDSection& getJCR() const { |
| assert(NULL != f_pJCR); |
| return *f_pJCR; |
| } |
| |
| LDSection& getNoteABITag() { |
| assert(NULL != f_pNoteABITag); |
| return *f_pNoteABITag; |
| } |
| |
| const LDSection& getNoteABITag() const { |
| assert(NULL != f_pNoteABITag); |
| return *f_pNoteABITag; |
| } |
| |
| LDSection& getStab() { |
| assert(NULL != f_pStab); |
| return *f_pStab; |
| } |
| |
| const LDSection& getStab() const { |
| assert(NULL != f_pStab); |
| return *f_pStab; |
| } |
| |
| LDSection& getStabStr() { |
| assert(NULL != f_pStabStr); |
| return *f_pStabStr; |
| } |
| |
| const LDSection& getStabStr() const { |
| assert(NULL != f_pStabStr); |
| return *f_pStabStr; |
| } |
| |
| LDSection& getStack() { |
| assert(NULL != f_pStack); |
| return *f_pStack; |
| } |
| |
| const LDSection& getStack() const { |
| assert(NULL != f_pStack); |
| return *f_pStack; |
| } |
| |
| LDSection& getStackNote() { |
| assert(NULL != f_pStackNote); |
| return *f_pStackNote; |
| } |
| |
| const LDSection& getStackNote() const { |
| assert(NULL != f_pStackNote); |
| return *f_pStackNote; |
| } |
| |
| LDSection& getDataRelRoLocal() { |
| assert(NULL != f_pDataRelRoLocal); |
| return *f_pDataRelRoLocal; |
| } |
| |
| const LDSection& getDataRelRoLocal() const { |
| assert(NULL != f_pDataRelRoLocal); |
| return *f_pDataRelRoLocal; |
| } |
| |
| protected: |
| // variable name : ELF |
| /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition. |
| LDSection* f_pNULLSection; |
| LDSection* f_pGOT; // .got |
| LDSection* f_pPLT; // .plt |
| LDSection* f_pRelDyn; // .rel.dyn |
| LDSection* f_pRelPlt; // .rel.plt |
| LDSection* f_pRelaDyn; // .rela.dyn |
| LDSection* f_pRelaPlt; // .rela.plt |
| |
| /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21. |
| LDSection* f_pComment; // .comment |
| LDSection* f_pData1; // .data1 |
| LDSection* f_pDebug; // .debug |
| LDSection* f_pDynamic; // .dynamic |
| LDSection* f_pDynStrTab; // .dynstr |
| LDSection* f_pDynSymTab; // .dynsym |
| LDSection* f_pFini; // .fini |
| LDSection* f_pFiniArray; // .fini_array |
| LDSection* f_pHashTab; // .hash |
| LDSection* f_pInit; // .init |
| LDSection* f_pInitArray; // .init_array |
| LDSection* f_pInterp; // .interp |
| LDSection* f_pLine; // .line |
| LDSection* f_pNote; // .note |
| LDSection* f_pPreInitArray; // .preinit_array |
| LDSection* f_pROData1; // .rodata1 |
| LDSection* f_pShStrTab; // .shstrtab |
| LDSection* f_pStrTab; // .strtab |
| LDSection* f_pSymTab; // .symtab |
| LDSection* f_pTBSS; // .tbss |
| LDSection* f_pTData; // .tdata |
| |
| /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24. |
| LDSection* f_pCtors; // .ctors |
| LDSection* f_pDataRelRo; // .data.rel.ro |
| LDSection* f_pDtors; // .dtors |
| LDSection* f_pEhFrame; // .eh_frame |
| LDSection* f_pEhFrameHdr; // .eh_frame_hdr |
| LDSection* f_pGCCExceptTable; // .gcc_except_table |
| LDSection* f_pGNUVersion; // .gnu.version |
| LDSection* f_pGNUVersionD; // .gnu.version_d |
| LDSection* f_pGNUVersionR; // .gnu.version_r |
| LDSection* f_pGOTPLT; // .got.plt |
| LDSection* f_pJCR; // .jcr |
| LDSection* f_pNoteABITag; // .note.ABI-tag |
| LDSection* f_pStab; // .stab |
| LDSection* f_pStabStr; // .stabstr |
| |
| /// practical |
| LDSection* f_pStack; // .stack |
| LDSection* f_pStackNote; // .note.GNU-stack |
| LDSection* f_pDataRelRoLocal; // .data.rel.ro.local |
| }; |
| |
| } // namespace of mcld |
| |
| #endif |
| |