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 
18 namespace mcld {
19 
20 /** \class ARMELFAttributeData
21  *  \brief ARMELFAttributeData handles public ("aeabi") attributes subsection in
22  *  ARM ELF.
23  *
24  */
25 class 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 {
133     R9_V6,
134     R9_SB,
135     R9_TLS,
136     R9_Unused
137   };
138 
139   // For Tag_ABI_PCS_RW_data
140   enum {
141     RW_data_Absolute,
142     RW_data_PC_Relative,
143     RW_data_SB_Relative,
144     RW_data_unused
145   };
146 
147 public:
148   // ARM [ABI-addenda], 2.2.2: A public attributes subsection is named aeabi.
ARMELFAttributeData()149   ARMELFAttributeData()
150     : ELFAttributeData("aeabi"), m_CurrentCPUArch(-1),
151       m_DIVUseInitialized(false), m_HardFPUseInitialized(false) { }
152 
153 public:
154   virtual const ELFAttributeValue *getAttributeValue(TagType pTag) const;
155 
156   virtual std::pair<ELFAttributeValue*, bool>
157       getOrCreateAttributeValue(TagType pTag);
158 
preMerge(const Input & pInput)159   virtual bool preMerge(const Input &pInput)
160   {
161     // Reset states.
162     m_CPUArch = -1;
163     m_CPUName.clear();
164     m_CPURawName.clear();
165     m_SecondaryCPUArch = -1;
166     m_VFPArgs = -1;
167     m_FPArch = -1;
168     m_HardFPUse = -1;
169     m_MPextensionUse = -1;
170     m_DIVUse = -1;
171     return true;
172   }
173 
174   virtual bool merge(const LinkerConfig& pConfig, const Input &pInput,
175                      TagType pTag, const ELFAttributeValue& pInAttr);
176 
177   virtual bool postMerge(const LinkerConfig& pConfig, const Input &pInput);
178 
179   virtual size_t sizeOutput() const;
180 
181   virtual size_t emit(char *pBuf) const;
182 
183   virtual bool usingThumb() const;
184 
185   virtual bool usingThumb2() const;
186 
187 private:
188   /// GetAttributeValueType - obtain the value type of the indicated tag.
189   static unsigned int GetAttributeValueType(TagType pTag);
190 
191 private:
192   // The storage for known tags which is indexed by the tag
193   ELFAttributeValue m_Attrs[Tag_Max + 1];
194 
195   // The storage for unknown tags
196   typedef std::map<TagType, ELFAttributeValue> UnknownAttrsMap;
197   UnknownAttrsMap m_UnknownAttrs;
198 
199   // This is a cache for the current output architecture calculate from of
200   // Tag_CPU_arch and Tag_also_compatible_with.
201   int m_CurrentCPUArch;
202 
203   // Value of Tag_DIV_use and Tag_ABI_HardFP_use requires further examination
204   // for the every time adding to the output. These booleans are initialized to
205   // false and set to true until the corresponding attribute is initialized.
206   bool m_DIVUseInitialized;
207   bool m_HardFPUseInitialized;
208 
209   // These attributes have dependency with each other. During the merge, we
210   // record their attribute values in the associated variables as follows and
211   // process them in postmerge() (when all other attributes are settled down.)
212 
213   // Record the value of input Tag_CPU_arch.
214   int m_CPUArch;
215 
216   // Record the value of input Tag_CPU_name.
217   std::string m_CPUName;
218 
219   // Record the value of input Tag_CPU_raw_name.
220   std::string m_CPURawName;
221 
222   // Record the value of input Tag_FP_arch.
223   int m_FPArch;
224 
225   // Record the value of input Tag_ABI_HardFP_use.
226   int m_HardFPUse;
227 
228   // Record the value of input Tag_also_compatible_with.
229   int m_SecondaryCPUArch;
230 
231   // Record the value of input Tag_ABI_VFP_args.
232   int m_VFPArgs;
233 
234   // Record the value of input Tag_MPextension_use and Tag_MPextension_use_legacy.
235   int m_MPextensionUse;
236 
237   // Record the value of input Tag_DIV_use.
238   int m_DIVUse;
239 };
240 
241 } // namespace of mcld
242 
243 #endif
244