ARMELFAttributeData.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- ARMELFAttributeData.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_ARM_ELF_ATTRIBUTE_DATA_H
10#define MCLD_ARM_ELF_ATTRIBUTE_DATA_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <mcld/Target/ELFAttributeData.h>
16#include <mcld/Target/ELFAttributeValue.h>
17
18#include <map>
19#include <string>
20
21namespace mcld {
22
23/** \class ARMELFAttributeData
24 *  \brief ARMELFAttributeData handles public ("aeabi") attributes subsection in
25 *  ARM ELF.
26 *
27 */
28class ARMELFAttributeData : public ELFAttributeData {
29public:
30  enum Tag {
31    // 0-3 are generic and are defined in ELFAttributeData.
32    Tag_CPU_raw_name                = 4,
33    Tag_CPU_name                    = 5,
34    Tag_CPU_arch                    = 6,
35    Tag_CPU_arch_profile            = 7,
36    Tag_ARM_ISA_use                 = 8,
37    Tag_THUMB_ISA_use               = 9,
38    Tag_FP_arch                     = 10,
39    Tag_WMMX_arch                   = 11,
40    Tag_Advanced_SIMD_arch          = 12,
41    Tag_PCS_config                  = 13,
42    Tag_ABI_PCS_R9_use              = 14,
43    Tag_ABI_PCS_RW_data             = 15,
44    Tag_ABI_PCS_RO_data             = 16,
45    Tag_ABI_PCS_GOT_use             = 17,
46    Tag_ABI_PCS_wchar_t             = 18,
47    Tag_ABI_FP_rounding             = 19,
48    Tag_ABI_FP_denormal             = 20,
49    Tag_ABI_FP_exceptions           = 21,
50    Tag_ABI_FP_user_exceptions      = 22,
51    Tag_ABI_FP_number_model         = 23,
52    Tag_ABI_align_needed            = 24,
53    Tag_ABI_align_preserved         = 25,
54    Tag_ABI_enum_size               = 26,
55    Tag_ABI_HardFP_use              = 27,
56    Tag_ABI_VFP_args                = 28,
57    Tag_ABI_WMMX_args               = 29,
58    Tag_ABI_optimization_goals      = 30,
59    Tag_ABI_FP_optimization_goals   = 31,
60    Tag_compatibility               = 32,
61
62    Tag_CPU_unaligned_access        = 34,
63
64    Tag_FP_HP_extension             = 36,
65
66    Tag_ABI_FP_16bit_format         = 38,
67
68    Tag_MPextension_use             = 42,
69
70    Tag_DIV_use                     = 44,
71
72    Tag_nodefaults                  = 64,
73    Tag_also_compatible_with        = 65,
74    Tag_T2EE_use                    = 66,
75    Tag_conformance                 = 67,
76    Tag_Virtualization_use          = 68,
77
78    Tag_MPextension_use_legacy      = 70,
79
80    Tag_Max = Tag_MPextension_use_legacy,
81
82    // Alias
83    Tag_VFP_arch                    = Tag_FP_arch,
84    Tag_ABI_align8_needed           = Tag_ABI_align_needed,
85    Tag_ABI_align8_preserved        = Tag_ABI_align_preserved,
86    Tag_VFP_HP_extension            = Tag_FP_HP_extension
87  };
88
89  // For Tag_CPU_arch
90  enum {
91    CPU_Arch_ARM_Pre_V4,
92    CPU_Arch_ARM_V4,    // e.g., SA110
93    CPU_Arch_ARM_V4T,   // e.g., ARM7TDMI
94    CPU_Arch_ARM_V5T,   // e.g., ARM9TDMI
95    CPU_Arch_ARM_V5TE,  // e.g., ARM946E-S
96    CPU_Arch_ARM_V5TEJ, // e.g., ARM926EJ-S
97    CPU_Arch_ARM_V6,    // e.g., ARM1136J-S
98    CPU_Arch_ARM_V6KZ,  // e.g., ARM1176JZ-S
99    CPU_Arch_ARM_V6T2,  // e.g., ARM1156T2F-S
100    CPU_Arch_ARM_V6K,   // e.g., ARM1136J-S
101    CPU_Arch_ARM_V7,    // e.g., Cortex A8, Cortex M3
102    CPU_Arch_ARM_V6_M,  // e.g., Cortex M1
103    CPU_Arch_ARM_V6S_M, // e.g., v6-M with the value of System extensions
104    CPU_Arch_ARM_V7E_M, // e.g., v7-M with DSP extensions
105    CPU_Arch_ARM_V8,
106
107    CPU_Arch_Max = CPU_Arch_ARM_V8,
108
109    // This is a pseudo-architecture to describe an architecture mixed with
110    // the subset of armv4t and armv6-m. This never appears in the value of
111    // Tag_CPU_arch.
112    CPU_Arch_ARM_V4T_Plus_V6_M = (CPU_Arch_Max + 1),
113
114    CPU_Arch_Plus_Pseudo_Max = CPU_Arch_ARM_V4T_Plus_V6_M,
115  };
116
117  // For Tag_CPU_arch_profile
118  enum {
119    Arch_Profile_None             = 0,
120    Arch_Profile_Application      = 'A',
121    Arch_Profile_Realtime         = 'R',
122    Arch_Profile_Microcontroller  = 'M',
123    Arch_Profile_RealOrApp        = 'S'
124  };
125
126  // For Tag_ABI_enum_size
127  enum {
128    Enum_Unused,
129    Enum_Smallest_Container,
130    Enum_32bit_Container,
131    Enum_Containerized_As_Possible
132  };
133
134  // For Tag_ABI_PCS_R9_use
135  enum {
136    R9_V6,
137    R9_SB,
138    R9_TLS,
139    R9_Unused
140  };
141
142  // For Tag_ABI_PCS_RW_data
143  enum {
144    RW_data_Absolute,
145    RW_data_PC_Relative,
146    RW_data_SB_Relative,
147    RW_data_unused
148  };
149
150public:
151  // ARM [ABI-addenda], 2.2.2: A public attributes subsection is named aeabi.
152  ARMELFAttributeData()
153    : ELFAttributeData("aeabi"), m_CurrentCPUArch(-1),
154      m_DIVUseInitialized(false), m_HardFPUseInitialized(false) { }
155
156public:
157  virtual const ELFAttributeValue *getAttributeValue(TagType pTag) const;
158
159  virtual std::pair<ELFAttributeValue*, bool>
160      getOrCreateAttributeValue(TagType pTag);
161
162  virtual bool preMerge(const Input &pInput)
163  {
164    // Reset states.
165    m_CPUArch = -1;
166    m_CPUName.clear();
167    m_CPURawName.clear();
168    m_SecondaryCPUArch = -1;
169    m_VFPArgs = -1;
170    m_FPArch = -1;
171    m_HardFPUse = -1;
172    m_MPextensionUse = -1;
173    m_DIVUse = -1;
174    return true;
175  }
176
177  virtual bool merge(const LinkerConfig& pConfig, const Input &pInput,
178                     TagType pTag, const ELFAttributeValue& pInAttr);
179
180  virtual bool postMerge(const LinkerConfig& pConfig, const Input &pInput);
181
182  virtual size_t sizeOutput() const;
183
184  virtual size_t emit(char *pBuf) const;
185
186private:
187  /// GetAttributeValueType - obtain the value type of the indicated tag.
188  static unsigned int GetAttributeValueType(TagType pTag);
189
190private:
191  // The storage for known tags which is indexed by the tag
192  ELFAttributeValue m_Attrs[Tag_Max + 1];
193
194  // The storage for unknown tags
195  typedef std::map<TagType, ELFAttributeValue> UnknownAttrsMap;
196  UnknownAttrsMap m_UnknownAttrs;
197
198  // This is a cache for the current output architecture calculate from of
199  // Tag_CPU_arch and Tag_also_compatible_with.
200  int m_CurrentCPUArch;
201
202  // Value of Tag_DIV_use and Tag_ABI_HardFP_use requires further examination
203  // for the every time adding to the output. These booleans are initialized to
204  // false and set to true until the corresponding attribute is initialized.
205  bool m_DIVUseInitialized;
206  bool m_HardFPUseInitialized;
207
208  // These attributes have dependency with each other. During the merge, we
209  // record their attribute values in the associated variables as follows and
210  // process them in postmerge() (when all other attributes are settled down.)
211
212  // Record the value of input Tag_CPU_arch.
213  int m_CPUArch;
214
215  // Record the value of input Tag_CPU_name.
216  std::string m_CPUName;
217
218  // Record the value of input Tag_CPU_raw_name.
219  std::string m_CPURawName;
220
221  // Record the value of input Tag_FP_arch.
222  int m_FPArch;
223
224  // Record the value of input Tag_ABI_HardFP_use.
225  int m_HardFPUse;
226
227  // Record the value of input Tag_also_compatible_with.
228  int m_SecondaryCPUArch;
229
230  // Record the value of input Tag_ABI_VFP_args.
231  int m_VFPArgs;
232
233  // Record the value of input Tag_MPextension_use and Tag_MPextension_use_legacy.
234  int m_MPextensionUse;
235
236  // Record the value of input Tag_DIV_use.
237  int m_DIVUse;
238};
239
240} // namespace of mcld
241
242#endif
243