//===- LDSection.h --------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_LD_LDSECTION_H #define MCLD_LD_LDSECTION_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <llvm/Support/DataTypes.h> #include <mcld/Support/Allocators.h> #include <mcld/Config/Config.h> #include <mcld/LD/LDFileFormat.h> #include <string> namespace mcld { class SectionData; class RelocData; class EhFrame; /** \class LDSection * \brief LDSection represents a section header entry. It is a unified * abstraction of a section header entry for various file formats. */ class LDSection { private: friend class Chunk<LDSection, MCLD_SECTIONS_PER_INPUT>; LDSection(); LDSection(const std::string& pName, LDFileFormat::Kind pKind, uint32_t pType, uint32_t pFlag, uint64_t pSize = 0, uint64_t pAddr = 0); public: ~LDSection(); static LDSection* Create(const std::string& pName, LDFileFormat::Kind pKind, uint32_t pType, uint32_t pFlag, uint64_t pSize = 0, uint64_t pAddr = 0); static void Destroy(LDSection*& pSection); static void Clear(); bool hasOffset() const; /// name - the name of this section. const std::string& name() const { return m_Name; } /// kind - the kind of this section, such as Text, BSS, GOT, and so on. /// from LDFileFormat::Kind LDFileFormat::Kind kind() const { return m_Kind; } /// type - The categorizes the section's contents and semantics. It's /// different from llvm::SectionKind. Type is format-dependent, but /// llvm::SectionKind is format independent and is used for bit-code. /// In ELF, it is sh_type /// In MachO, it's type field of struct section::flags uint32_t type() const { return m_Type; } /// flag - An integer describes miscellaneous attributes. /// In ELF, it is sh_flags. /// In MachO, it's attribute field of struct section::flags uint32_t flag() const { return m_Flag; } /// size - An integer specifying the size in bytes of the virtual memory /// occupied by this section. /// In ELF, if the type() is SHT_NOBITS, this function return zero. /// Before layouting, output's LDSection::size() should return zero. uint64_t size() const { return m_Size; } /// offset - An integer specifying the offset of this section in the file. /// Before layouting, output's LDSection::offset() should return zero. uint64_t offset() const { return m_Offset; } /// addr - An integer specifying the virtual address of this section in the /// virtual image. /// Before layouting, output's LDSection::offset() should return zero. /// ELF uses sh_addralign to set alignment constraints. In LLVM, alignment /// constraint is set in SectionData::setAlignment. addr() contains the /// original ELF::sh_addr. Modulo sh_addr by sh_addralign is not necessary. /// MachO uses the same scenario. /// /// Because addr() in output is changing during linking, MCLinker does not /// store the address of the output here. The address is in Layout uint64_t addr() const { return m_Addr; } /// align - An integer specifying the align of this section in the file. /// Before layouting, output's LDSection::align() should return zero. uint32_t align() const { return m_Align; } size_t index() const { return m_Index; } /// getLink - return the Link. When a section A needs the other section B /// during linking or loading, we say B is A's Link section. /// In ELF, InfoLink section control the ElfNN_Shdr::sh_link and sh_info. /// /// @return if the section needs no other sections, return NULL LDSection* getLink() { return m_pLink; } const LDSection* getLink() const { return m_pLink; } size_t getInfo() const { return m_Info; } void setKind(LDFileFormat::Kind pKind) { m_Kind = pKind; } void setSize(uint64_t size) { m_Size = size; } void setOffset(uint64_t Offset) { m_Offset = Offset; } void setAddr(uint64_t addr) { m_Addr = addr; } void setAlign(uint32_t align) { m_Align = align; } void setFlag(uint32_t flag) { m_Flag = flag; } void setType(uint32_t type) { m_Type = type; } // ----- SectionData ----- // const SectionData* getSectionData() const { return m_Data.sect_data; } SectionData* getSectionData() { return m_Data.sect_data; } void setSectionData(SectionData* pSD) { m_Data.sect_data = pSD; } bool hasSectionData() const; // ------ RelocData ------ // const RelocData* getRelocData() const { return m_Data.reloc_data; } RelocData* getRelocData() { return m_Data.reloc_data; } void setRelocData(RelocData* pRD) { m_Data.reloc_data = pRD; } bool hasRelocData() const; // ------ EhFrame ------ // const EhFrame* getEhFrame() const { return m_Data.eh_frame; } EhFrame* getEhFrame() { return m_Data.eh_frame; } void setEhFrame(EhFrame* pEhFrame) { m_Data.eh_frame = pEhFrame; } bool hasEhFrame() const; /// setLink - set the sections should link with. /// if pLink is NULL, no Link section is set. void setLink(LDSection* pLink) { m_pLink = pLink; } void setInfo(size_t pInfo) { m_Info = pInfo; } void setIndex(size_t pIndex) { m_Index = pIndex; } private: union SectOrRelocData { SectionData* sect_data; RelocData* reloc_data; EhFrame* eh_frame; }; private: std::string m_Name; LDFileFormat::Kind m_Kind; uint32_t m_Type; uint32_t m_Flag; uint64_t m_Size; uint64_t m_Offset; uint64_t m_Addr; uint32_t m_Align; size_t m_Info; LDSection* m_pLink; /// m_Data - the SectionData or RelocData of this section SectOrRelocData m_Data; /// m_Index - the index of the file size_t m_Index; }; // end of LDSection } // end namespace mcld #endif