ELFAttribute.h revision 533eae20118036f425f27bf0536ef0ccbb090b65
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
18namespace mcld {
19
20class ELFAttributeData;
21class GNULDBackend;
22class Input;
23class LDSection;
24class LinkerConfig;
25
26/** \class ELFAttribute
27 *  \brief ELFAttribute is the attribute section in an ELF file.
28 */
29class ELFAttribute
30{
31public:
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
50public:
51  ELFAttribute(const GNULDBackend &pBackend, const LinkerConfig& pConfig)
52    : m_Backend(pBackend), m_Config(pConfig) { }
53
54  ~ELFAttribute();
55
56public:
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
74private:
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
111private:
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