1 //===- ELFAttribute.h -----------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_TARGET_ELFATTRIBUTE_H 10 #define MCLD_TARGET_ELFATTRIBUTE_H 11 12 #include <mcld/Support/MemoryRegion.h> 13 #include <mcld/Target/ELFAttributeData.h> 14 15 #include <llvm/ADT/SmallVector.h> 16 #include <llvm/ADT/StringRef.h> 17 18 namespace mcld { 19 20 class ELFAttributeData; 21 class GNULDBackend; 22 class Input; 23 class LDSection; 24 class LinkerConfig; 25 26 /** \class ELFAttribute 27 * \brief ELFAttribute is the attribute section in an ELF file. 28 */ 29 class ELFAttribute 30 { 31 public: 32 // ARM [ABI-addenda], 2.2.3. 33 static const char FormatVersion = 'A'; 34 static const size_t FormatVersionFieldSize = sizeof(FormatVersion); // a byte 35 static const size_t SubsectionLengthFieldSize = 4; // a 4-byte integer 36 37 // MinimalELFAttributeSubsectionSize is the minimal number of bytes a valid 38 // subsection in ELF attribute section should have. 39 static const size_t MinimalELFAttributeSubsectionSize 40 = 1 /* Tag_File, see ARM [ABI-addenda], 2.2.4 */ + 41 4 /* byte-size, see ARM [ABI-addenda], 2.2.4 */; 42 43 // MinimalELFAttributeSectionSize is the minimal number of bytes a valid ELF 44 // attribute section should have. 45 static const size_t MinimalELFAttributeSectionSize 46 = FormatVersionFieldSize + SubsectionLengthFieldSize + 47 2 /* vendor-name, a char plus '\0', see ARM [ABI-addenda], 2.2.3 */ + 48 1 * MinimalELFAttributeSubsectionSize; 49 50 public: 51 ELFAttribute(const GNULDBackend &pBackend, const LinkerConfig& pConfig) 52 : m_Backend(pBackend), m_Config(pConfig) { } 53 54 ~ELFAttribute(); 55 56 public: 57 /// merge - merge attributes from input (attribute) section 58 bool merge(const Input &pInput, LDSection &pInputAttrSectHdr); 59 60 /// sizeOutput - calculate the number of bytes required to encode this 61 /// attribute data section 62 size_t sizeOutput() const; 63 64 /// emit - encode and write out this attribute section 65 size_t emit(MemoryRegion &pRegion) const; 66 67 inline const GNULDBackend &backend() const { return m_Backend; } 68 69 inline const LinkerConfig &config() const { return m_Config; } 70 71 // Place vendor's attribute data under the management. 72 void registerAttributeData(ELFAttributeData& pAttrData); 73 74 private: 75 /** \class Subsection 76 * \brief A helper class to wrap ELFAttributeData and to provide general 77 * interfaces for ELFAttribute to operate on 78 */ 79 class Subsection { 80 public: 81 Subsection(ELFAttribute &pParent, ELFAttributeData &pAttrData) 82 : m_Parent(pParent), m_AttrData(pAttrData) { } 83 84 public: 85 bool isMyAttribute(llvm::StringRef pVendorName) const 86 { 87 return (m_AttrData.getVendorName() == pVendorName); 88 } 89 90 /// merge - Merge the attributes from the section in the input data. 91 bool merge(const Input &pInput, ConstAddress pData, size_t pSize); 92 93 /// sizeOutput - calculate the number of bytes required to encode this 94 /// subsection 95 size_t sizeOutput() const; 96 97 /// emit - write out this attribute subsection to the buffer. 98 size_t emit(char *pBuf) const; 99 100 private: 101 // The attribute section this subsection belongs to 102 ELFAttribute &m_Parent; 103 104 // The attribute data containing in this subsection 105 ELFAttributeData &m_AttrData; 106 }; 107 108 // Obtain the corresponding subsection of the specified vendor 109 Subsection *getSubsection(llvm::StringRef pVendorName) const; 110 111 private: 112 const GNULDBackend &m_Backend; 113 114 const LinkerConfig &m_Config; 115 116 // There is at most two subsections ("aeabi" and "gnu") in most cases. 117 llvm::SmallVector<Subsection*, 2> m_Subsections; 118 }; 119 120 } // namespace of mcld 121 122 #endif 123