Home | History | Annotate | Download | only in ARM
      1 //===- ARMException.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_ARMEXCEPTION_H_
     10 #define TARGET_ARM_ARMEXCEPTION_H_
     11 
     12 #include <llvm/ADT/PointerUnion.h>
     13 #include <llvm/ADT/StringRef.h>
     14 
     15 #include <map>
     16 #include <memory>
     17 #include <string>
     18 
     19 namespace mcld {
     20 
     21 class Fragment;
     22 class Input;
     23 class LDSection;
     24 class RegionFragment;
     25 class RelocData;
     26 
     27 /// ARMExSectionTuple - Tuple of associated exception handling sections
     28 class ARMExSectionTuple {
     29  public:
     30   ARMExSectionTuple()
     31       : m_pTextSection(NULL),
     32         m_pExIdxSection(NULL),
     33         m_pExTabSection(NULL),
     34         m_pRelExIdxSection(NULL),
     35         m_pRelExTabSection(NULL) {
     36   }
     37 
     38   LDSection* getTextSection() const {
     39     return m_pTextSection;
     40   }
     41 
     42   LDSection* getExIdxSection() const {
     43     return m_pExIdxSection;
     44   }
     45 
     46   LDSection* getExTabSection() const {
     47     return m_pExTabSection;
     48   }
     49 
     50   LDSection* getRelExIdxSection() const {
     51     return m_pRelExIdxSection;
     52   }
     53 
     54   LDSection* getRelExTabSection() const {
     55     return m_pRelExTabSection;
     56   }
     57 
     58   void setTextSection(LDSection* pSection) {
     59     m_pTextSection = pSection;
     60   }
     61 
     62   void setExIdxSection(LDSection* pSection) {
     63     m_pExIdxSection = pSection;
     64   }
     65 
     66   void setExTabSection(LDSection* pSection) {
     67     m_pExTabSection = pSection;
     68   }
     69 
     70   void setRelExIdxSection(LDSection* pSection) {
     71     m_pRelExIdxSection = pSection;
     72   }
     73 
     74   void setRelExTabSection(LDSection* pSection) {
     75     m_pRelExTabSection = pSection;
     76   }
     77 
     78   RegionFragment* getTextFragment() const {
     79     return m_pTextFragment;
     80   }
     81 
     82   RegionFragment* getExIdxFragment() const {
     83     return m_pExIdxFragment;
     84   }
     85 
     86   RegionFragment* getExTabFragment() const {
     87     return m_pExTabFragment;
     88   }
     89 
     90   RelocData* getExIdxRelocData() const {
     91     return m_pExIdxRelocData;
     92   }
     93 
     94   RelocData* getExTabRelocData() const {
     95     return m_pExTabRelocData;
     96   }
     97 
     98   void setTextFragment(RegionFragment* pFragment) {
     99     m_pTextFragment = pFragment;
    100   }
    101 
    102   void setExIdxFragment(RegionFragment* pFragment) {
    103     m_pExIdxFragment = pFragment;
    104   }
    105 
    106   void setExTabFragment(RegionFragment* pFragment) {
    107     m_pExTabFragment = pFragment;
    108   }
    109 
    110   void setExIdxRelocData(RelocData* pRelocData) {
    111     m_pExIdxRelocData = pRelocData;
    112   }
    113 
    114   void setExTabRelocData(RelocData* pRelocData) {
    115     m_pExTabRelocData = pRelocData;
    116   }
    117 
    118  private:
    119   // .text section
    120   union {
    121     LDSection*      m_pTextSection;
    122     RegionFragment* m_pTextFragment;
    123   };
    124 
    125   // .ARM.exidx section
    126   union {
    127     LDSection*      m_pExIdxSection;
    128     RegionFragment* m_pExIdxFragment;
    129   };
    130 
    131   // .ARM.extab section
    132   union {
    133     LDSection*      m_pExTabSection;
    134     RegionFragment* m_pExTabFragment;
    135   };
    136 
    137   // .rel.ARM.exidx section
    138   union {
    139     LDSection*      m_pRelExIdxSection;
    140     RelocData*      m_pExIdxRelocData;
    141   };
    142 
    143   // .rel.ARM.extab section
    144   union {
    145     LDSection*      m_pRelExTabSection;
    146     RelocData*      m_pExTabRelocData;
    147   };
    148 };
    149 
    150 /// ARMInputExMap - ARM exception handling data of an Input
    151 class ARMInputExMap {
    152  public:
    153   typedef std::map<std::string, std::unique_ptr<ARMExSectionTuple> > NameMap;
    154   typedef NameMap::iterator iterator;
    155   typedef NameMap::const_iterator const_iterator;
    156 
    157  public:
    158   ARMInputExMap() { }
    159 
    160   /// get - Get the ARMExSectionTuple by the corresponding text section name.
    161   /// As an exception, to get the ARMExSectionTuple for .text section, use ""
    162   /// as the section name instead.
    163   ARMExSectionTuple* get(const char* pName) const {
    164     NameMap::const_iterator it = m_NameToExData.find(pName);
    165     if (it == m_NameToExData.end()) {
    166       return NULL;
    167     }
    168     return it->second.get();
    169   }
    170 
    171   ARMExSectionTuple* getByExSection(llvm::StringRef pName) const {
    172     assert((pName.startswith(".ARM.exidx") ||
    173             pName.startswith(".ARM.extab")) &&
    174            "Not a .ARM.exidx section name");
    175     return get(pName.data() + sizeof(".ARM.ex***") - 1);
    176   }
    177 
    178   ARMExSectionTuple* getByRelExSection(llvm::StringRef pName) const {
    179     assert((pName.startswith(".rel.ARM.exidx") ||
    180             pName.startswith(".rel.ARM.extab")) &&
    181            "Not a .rel.ARM.exidx section name");
    182     return get(pName.data() + sizeof(".rel.ARM.ex***") - 1);
    183   }
    184 
    185   /// getOrCreate - Get an existing or create a new ARMExSectionTuple which is
    186   /// associated with the text section name.  As an exception, use "" as the
    187   /// section name for .text section.
    188   ARMExSectionTuple* getOrCreate(const char* pName) {
    189     std::unique_ptr<ARMExSectionTuple>& result = m_NameToExData[pName];
    190     if (!result) {
    191       result.reset(new ARMExSectionTuple());
    192     }
    193     return result.get();
    194   }
    195 
    196   ARMExSectionTuple* getOrCreateByExSection(llvm::StringRef pName) {
    197     assert((pName.startswith(".ARM.exidx") ||
    198             pName.startswith(".ARM.extab")) &&
    199            "Not a .ARM.exidx section name");
    200     return getOrCreate(pName.data() + sizeof(".ARM.ex***") - 1);
    201   }
    202 
    203   ARMExSectionTuple* getOrCreateByRelExSection(llvm::StringRef pName) {
    204     assert((pName.startswith(".rel.ARM.exidx") ||
    205             pName.startswith(".rel.ARM.extab")) &&
    206            "Not a .rel.ARM.exidx section name");
    207     return getOrCreate(pName.data() + sizeof(".rel.ARM.ex***") - 1);
    208   }
    209 
    210   /// begin - return the iterator to the begin of the map
    211   iterator       begin()       { return m_NameToExData.begin(); }
    212   const_iterator begin() const { return m_NameToExData.begin(); }
    213 
    214   /// end - return the iterator to the end of the map
    215   iterator       end()       { return m_NameToExData.end(); }
    216   const_iterator end() const { return m_NameToExData.end(); }
    217 
    218   /// erase - remove an entry from the map
    219   void erase(iterator it) { m_NameToExData.erase(it); }
    220 
    221  private:
    222   NameMap m_NameToExData;
    223 };
    224 
    225 /// ARMExData - ARM exception handling data of a module
    226 class ARMExData {
    227  private:
    228   typedef std::map<Input*, std::unique_ptr<ARMInputExMap> > InputMap;
    229 
    230   typedef std::map<const Fragment*, ARMExSectionTuple*> ExIdxMap;
    231 
    232  public:
    233   ARMExData() { }
    234 
    235   // addInputMap - register the ARMInputExMap with associated pInput
    236   void addInputMap(Input* pInput,
    237                    std::unique_ptr<ARMInputExMap>&& pExMap);
    238 
    239   // getInputMap - get the ARMInputExMap corresponding to pInput
    240   ARMInputExMap* getInputMap(Input* pInput) const {
    241     InputMap::const_iterator it = m_Inputs.find(pInput);
    242     if (it == m_Inputs.end()) {
    243       return NULL;
    244     }
    245     return it->second.get();
    246   }
    247 
    248   // getTupleByExIdx - get the ARMExSectionTuple corresponding to pExIdxFragment
    249   ARMExSectionTuple* getTupleByExIdx(const Fragment* pExIdxFragment) const {
    250     ExIdxMap::const_iterator it = m_ExIdxToTuple.find(pExIdxFragment);
    251     if (it == m_ExIdxToTuple.end()) {
    252       return NULL;
    253     }
    254     return it->second;
    255   }
    256 
    257  private:
    258   // Map from Input to ARMInputExMap
    259   InputMap m_Inputs;
    260 
    261   // Map from .ARM.exidx RegionFragment to ARMExSectionTuple
    262   ExIdxMap m_ExIdxToTuple;
    263 };
    264 
    265 }  // namespace mcld
    266 
    267 #endif  // TARGET_ARM_ARMEXCEPTION_H_
    268