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 { 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. ARMELFAttributeData()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 preMerge(const Input & pInput)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