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