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