//===- ELFAttribute.h -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_TARGET_ELFATTRIBUTE_H_ #define MCLD_TARGET_ELFATTRIBUTE_H_ #include "mcld/Support/MemoryRegion.h" #include "mcld/Target/ELFAttributeData.h" #include #include namespace mcld { class ELFAttributeData; class GNULDBackend; class Input; class LDSection; class LinkerConfig; /** \class ELFAttribute * \brief ELFAttribute is the attribute section in an ELF file. */ class ELFAttribute { public: // ARM [ABI-addenda], 2.2.3. static const char FormatVersion = 'A'; static const size_t FormatVersionFieldSize = sizeof(FormatVersion); // a byte static const size_t SubsectionLengthFieldSize = 4; // a 4-byte integer // MinimalELFAttributeSubsectionSize is the minimal number of bytes a valid // subsection in ELF attribute section should have. static const size_t MinimalELFAttributeSubsectionSize = 1 /* Tag_File, see ARM [ABI-addenda], 2.2.4 */ + 4 /* byte-size, see ARM [ABI-addenda], 2.2.4 */; // MinimalELFAttributeSectionSize is the minimal number of bytes a valid ELF // attribute section should have. static const size_t MinimalELFAttributeSectionSize = FormatVersionFieldSize + SubsectionLengthFieldSize + 2 /* vendor-name, a char plus '\0', see ARM [ABI-addenda], 2.2.3 */ + 1 * MinimalELFAttributeSubsectionSize; public: ELFAttribute(const GNULDBackend& pBackend, const LinkerConfig& pConfig) : m_Backend(pBackend), m_Config(pConfig) {} ~ELFAttribute(); public: /// merge - merge attributes from input (attribute) section bool merge(const Input& pInput, LDSection& pInputAttrSectHdr); /// sizeOutput - calculate the number of bytes required to encode this /// attribute data section size_t sizeOutput() const; /// emit - encode and write out this attribute section size_t emit(MemoryRegion& pRegion) const; inline const GNULDBackend& backend() const { return m_Backend; } inline const LinkerConfig& config() const { return m_Config; } // Place vendor's attribute data under the management. void registerAttributeData(ELFAttributeData& pAttrData); private: /** \class Subsection * \brief A helper class to wrap ELFAttributeData and to provide general * interfaces for ELFAttribute to operate on */ class Subsection { public: Subsection(ELFAttribute& pParent, ELFAttributeData& pAttrData) : m_Parent(pParent), m_AttrData(pAttrData) {} public: bool isMyAttribute(llvm::StringRef pVendorName) const { return (m_AttrData.getVendorName() == pVendorName); } /// merge - Merge the attributes from the section in the input data. bool merge(const Input& pInput, ConstAddress pData, size_t pSize); /// sizeOutput - calculate the number of bytes required to encode this /// subsection size_t sizeOutput() const; /// emit - write out this attribute subsection to the buffer. size_t emit(char* pBuf) const; private: // The attribute section this subsection belongs to ELFAttribute& m_Parent; // The attribute data containing in this subsection ELFAttributeData& m_AttrData; }; // Obtain the corresponding subsection of the specified vendor Subsection* getSubsection(llvm::StringRef pVendorName) const; private: const GNULDBackend& m_Backend; const LinkerConfig& m_Config; // There is at most two subsections ("aeabi" and "gnu") in most cases. llvm::SmallVector m_Subsections; }; } // namespace mcld #endif // MCLD_TARGET_ELFATTRIBUTE_H_