| //===- ARMELFAttributeData.h ----------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef TARGET_ARM_ARMELFATTRIBUTEDATA_H_ |
| #define TARGET_ARM_ARMELFATTRIBUTEDATA_H_ |
| |
| #include "mcld/Target/ELFAttributeData.h" |
| #include "mcld/Target/ELFAttributeValue.h" |
| |
| #include <map> |
| #include <string> |
| |
| namespace mcld { |
| |
| /** \class ARMELFAttributeData |
| * \brief ARMELFAttributeData handles public ("aeabi") attributes subsection in |
| * ARM ELF. |
| * |
| */ |
| class ARMELFAttributeData : public ELFAttributeData { |
| public: |
| enum Tag { |
| // 0-3 are generic and are defined in ELFAttributeData. |
| Tag_CPU_raw_name = 4, |
| Tag_CPU_name = 5, |
| Tag_CPU_arch = 6, |
| Tag_CPU_arch_profile = 7, |
| Tag_ARM_ISA_use = 8, |
| Tag_THUMB_ISA_use = 9, |
| Tag_FP_arch = 10, |
| Tag_WMMX_arch = 11, |
| Tag_Advanced_SIMD_arch = 12, |
| Tag_PCS_config = 13, |
| Tag_ABI_PCS_R9_use = 14, |
| Tag_ABI_PCS_RW_data = 15, |
| Tag_ABI_PCS_RO_data = 16, |
| Tag_ABI_PCS_GOT_use = 17, |
| Tag_ABI_PCS_wchar_t = 18, |
| Tag_ABI_FP_rounding = 19, |
| Tag_ABI_FP_denormal = 20, |
| Tag_ABI_FP_exceptions = 21, |
| Tag_ABI_FP_user_exceptions = 22, |
| Tag_ABI_FP_number_model = 23, |
| Tag_ABI_align_needed = 24, |
| Tag_ABI_align_preserved = 25, |
| Tag_ABI_enum_size = 26, |
| Tag_ABI_HardFP_use = 27, |
| Tag_ABI_VFP_args = 28, |
| Tag_ABI_WMMX_args = 29, |
| Tag_ABI_optimization_goals = 30, |
| Tag_ABI_FP_optimization_goals = 31, |
| Tag_compatibility = 32, |
| |
| Tag_CPU_unaligned_access = 34, |
| |
| Tag_FP_HP_extension = 36, |
| |
| Tag_ABI_FP_16bit_format = 38, |
| |
| Tag_MPextension_use = 42, |
| |
| Tag_DIV_use = 44, |
| |
| Tag_nodefaults = 64, |
| Tag_also_compatible_with = 65, |
| Tag_T2EE_use = 66, |
| Tag_conformance = 67, |
| Tag_Virtualization_use = 68, |
| |
| Tag_MPextension_use_legacy = 70, |
| |
| Tag_Max = Tag_MPextension_use_legacy, |
| |
| // Alias |
| Tag_VFP_arch = Tag_FP_arch, |
| Tag_ABI_align8_needed = Tag_ABI_align_needed, |
| Tag_ABI_align8_preserved = Tag_ABI_align_preserved, |
| Tag_VFP_HP_extension = Tag_FP_HP_extension |
| }; |
| |
| // For Tag_CPU_arch |
| enum { |
| CPU_Arch_ARM_Pre_V4, |
| CPU_Arch_ARM_V4, // e.g., SA110 |
| CPU_Arch_ARM_V4T, // e.g., ARM7TDMI |
| CPU_Arch_ARM_V5T, // e.g., ARM9TDMI |
| CPU_Arch_ARM_V5TE, // e.g., ARM946E-S |
| CPU_Arch_ARM_V5TEJ, // e.g., ARM926EJ-S |
| CPU_Arch_ARM_V6, // e.g., ARM1136J-S |
| CPU_Arch_ARM_V6KZ, // e.g., ARM1176JZ-S |
| CPU_Arch_ARM_V6T2, // e.g., ARM1156T2F-S |
| CPU_Arch_ARM_V6K, // e.g., ARM1136J-S |
| CPU_Arch_ARM_V7, // e.g., Cortex A8, Cortex M3 |
| CPU_Arch_ARM_V6_M, // e.g., Cortex M1 |
| CPU_Arch_ARM_V6S_M, // e.g., v6-M with the value of System extensions |
| CPU_Arch_ARM_V7E_M, // e.g., v7-M with DSP extensions |
| CPU_Arch_ARM_V8, |
| |
| CPU_Arch_Max = CPU_Arch_ARM_V8, |
| |
| // This is a pseudo-architecture to describe an architecture mixed with |
| // the subset of armv4t and armv6-m. This never appears in the value of |
| // Tag_CPU_arch. |
| CPU_Arch_ARM_V4T_Plus_V6_M = (CPU_Arch_Max + 1), |
| |
| CPU_Arch_Plus_Pseudo_Max = CPU_Arch_ARM_V4T_Plus_V6_M, |
| }; |
| |
| // For Tag_CPU_arch_profile |
| enum { |
| Arch_Profile_None = 0, |
| Arch_Profile_Application = 'A', |
| Arch_Profile_Realtime = 'R', |
| Arch_Profile_Microcontroller = 'M', |
| Arch_Profile_RealOrApp = 'S' |
| }; |
| |
| // For Tag_ABI_enum_size |
| enum { |
| Enum_Unused, |
| Enum_Smallest_Container, |
| Enum_32bit_Container, |
| Enum_Containerized_As_Possible |
| }; |
| |
| // For Tag_ABI_PCS_R9_use |
| enum { R9_V6, R9_SB, R9_TLS, R9_Unused }; |
| |
| // For Tag_ABI_PCS_RW_data |
| enum { |
| RW_data_Absolute, |
| RW_data_PC_Relative, |
| RW_data_SB_Relative, |
| RW_data_unused |
| }; |
| |
| public: |
| // ARM [ABI-addenda], 2.2.2: A public attributes subsection is named aeabi. |
| ARMELFAttributeData() |
| : ELFAttributeData("aeabi"), |
| m_CurrentCPUArch(-1), |
| m_DIVUseInitialized(false), |
| m_HardFPUseInitialized(false) {} |
| |
| public: |
| virtual const ELFAttributeValue* getAttributeValue(TagType pTag) const; |
| |
| virtual std::pair<ELFAttributeValue*, bool> getOrCreateAttributeValue( |
| TagType pTag); |
| |
| virtual bool preMerge(const Input& pInput) { |
| // Reset states. |
| m_CPUArch = -1; |
| m_CPUName.clear(); |
| m_CPURawName.clear(); |
| m_SecondaryCPUArch = -1; |
| m_VFPArgs = -1; |
| m_FPArch = -1; |
| m_HardFPUse = -1; |
| m_MPextensionUse = -1; |
| m_DIVUse = -1; |
| return true; |
| } |
| |
| virtual bool merge(const LinkerConfig& pConfig, |
| const Input& pInput, |
| TagType pTag, |
| const ELFAttributeValue& pInAttr); |
| |
| virtual bool postMerge(const LinkerConfig& pConfig, const Input& pInput); |
| |
| virtual size_t sizeOutput() const; |
| |
| virtual size_t emit(char* pBuf) const; |
| |
| virtual bool usingThumb() const; |
| |
| virtual bool usingThumb2() const; |
| |
| private: |
| /// GetAttributeValueType - obtain the value type of the indicated tag. |
| static unsigned int GetAttributeValueType(TagType pTag); |
| |
| private: |
| // The storage for known tags which is indexed by the tag |
| ELFAttributeValue m_Attrs[Tag_Max + 1]; |
| |
| // The storage for unknown tags |
| typedef std::map<TagType, ELFAttributeValue> UnknownAttrsMap; |
| UnknownAttrsMap m_UnknownAttrs; |
| |
| // This is a cache for the current output architecture calculate from of |
| // Tag_CPU_arch and Tag_also_compatible_with. |
| int m_CurrentCPUArch; |
| |
| // Value of Tag_DIV_use and Tag_ABI_HardFP_use requires further examination |
| // for the every time adding to the output. These booleans are initialized to |
| // false and set to true until the corresponding attribute is initialized. |
| bool m_DIVUseInitialized; |
| bool m_HardFPUseInitialized; |
| |
| // These attributes have dependency with each other. During the merge, we |
| // record their attribute values in the associated variables as follows and |
| // process them in postmerge() (when all other attributes are settled down.) |
| |
| // Record the value of input Tag_CPU_arch. |
| int m_CPUArch; |
| |
| // Record the value of input Tag_CPU_name. |
| std::string m_CPUName; |
| |
| // Record the value of input Tag_CPU_raw_name. |
| std::string m_CPURawName; |
| |
| // Record the value of input Tag_FP_arch. |
| int m_FPArch; |
| |
| // Record the value of input Tag_ABI_HardFP_use. |
| int m_HardFPUse; |
| |
| // Record the value of input Tag_also_compatible_with. |
| int m_SecondaryCPUArch; |
| |
| // Record the value of input Tag_ABI_VFP_args. |
| int m_VFPArgs; |
| |
| // Record the value of input Tag_MPextension_use and |
| // Tag_MPextension_use_legacy. |
| int m_MPextensionUse; |
| |
| // Record the value of input Tag_DIV_use. |
| int m_DIVUse; |
| }; |
| |
| } // namespace mcld |
| |
| #endif // TARGET_ARM_ARMELFATTRIBUTEDATA_H_ |