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