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