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:
ELFAttribute(const GNULDBackend & pBackend,const LinkerConfig & pConfig)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 
backend()67   inline const GNULDBackend &backend() const { return m_Backend; }
68 
config()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:
Subsection(ELFAttribute & pParent,ELFAttributeData & pAttrData)81     Subsection(ELFAttribute &pParent, ELFAttributeData &pAttrData)
82       : m_Parent(pParent), m_AttrData(pAttrData) { }
83 
84   public:
isMyAttribute(llvm::StringRef pVendorName)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