Home | History | Annotate | Download | only in ARM
      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.
    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 
    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