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. 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 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