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 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:
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
66  inline const GNULDBackend& backend() const { return m_Backend; }
67
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:
80    Subsection(ELFAttribute& pParent, ELFAttributeData& pAttrData)
81        : m_Parent(pParent), m_AttrData(pAttrData) {}
82
83   public:
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