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 "mcld/LD/LDSection.h"
     13 
     14 #include <llvm/ADT/PointerUnion.h>
     15 #include <llvm/ADT/StringRef.h>
     16 #include <llvm/Support/ELF.h>
     17 
     18 #include <map>
     19 #include <memory>
     20 #include <string>
     21 
     22 namespace mcld {
     23 
     24 class Fragment;
     25 class Input;
     26 class LDSection;
     27 class Module;
     28 class RegionFragment;
     29 class RelocData;
     30 
     31 /// ARMExSectionTuple - Tuple of associated exception handling sections
     32 class ARMExSectionTuple {
     33  public:
     34   ARMExSectionTuple()
     35       : m_pTextSection(NULL),
     36         m_pExIdxSection(NULL) {
     37   }
     38 
     39   LDSection* getTextSection() const {
     40     return m_pTextSection;
     41   }
     42 
     43   LDSection* getExIdxSection() const {
     44     return m_pExIdxSection;
     45   }
     46 
     47   void setTextSection(LDSection* pSection) {
     48     m_pTextSection = pSection;
     49   }
     50 
     51   void setExIdxSection(LDSection* pSection) {
     52     m_pExIdxSection = pSection;
     53   }
     54 
     55   RegionFragment* getTextFragment() const {
     56     return m_pTextFragment;
     57   }
     58 
     59   RegionFragment* getExIdxFragment() const {
     60     return m_pExIdxFragment;
     61   }
     62 
     63   void setTextFragment(RegionFragment* pFragment) {
     64     m_pTextFragment = pFragment;
     65   }
     66 
     67   void setExIdxFragment(RegionFragment* pFragment) {
     68     m_pExIdxFragment = pFragment;
     69   }
     70 
     71  private:
     72   // .text section
     73   union {
     74     LDSection*      m_pTextSection;
     75     RegionFragment* m_pTextFragment;
     76   };
     77 
     78   // .ARM.exidx section
     79   union {
     80     LDSection*      m_pExIdxSection;
     81     RegionFragment* m_pExIdxFragment;
     82   };
     83 };
     84 
     85 /// ARMInputExMap - ARM exception handling section mapping of a mcld::Input.
     86 class ARMInputExMap {
     87  public:
     88   typedef std::map<LDSection*, std::unique_ptr<ARMExSectionTuple> > SectMap;
     89   typedef SectMap::iterator iterator;
     90   typedef SectMap::const_iterator const_iterator;
     91 
     92  public:
     93   // create - Build the exception handling section mapping of a mcld::Input.
     94   static std::unique_ptr<ARMInputExMap> create(Input &input);
     95 
     96   /// getByExSection - Get the ARMExSectionTuple by the address of the
     97   /// .ARM.exidx section.
     98   ARMExSectionTuple* getByExSection(LDSection &pSect) const {
     99     assert(pSect.type() == llvm::ELF::SHT_ARM_EXIDX);
    100     SectMap::const_iterator it = m_SectToExData.find(&pSect);
    101     if (it == m_SectToExData.end()) {
    102       return NULL;
    103     }
    104     return it->second.get();
    105   }
    106 
    107   /// getOrCreate - Get an existing or create a new ARMExSectionTuple which is
    108   /// associated with the address of the .ARM.exidx section.
    109   ARMExSectionTuple* getOrCreateByExSection(LDSection &pSect) {
    110     assert(pSect.type() == llvm::ELF::SHT_ARM_EXIDX);
    111     std::unique_ptr<ARMExSectionTuple>& result = m_SectToExData[&pSect];
    112     if (!result) {
    113       result.reset(new ARMExSectionTuple());
    114     }
    115     return result.get();
    116   }
    117 
    118   /// begin - return the iterator to the begin of the map
    119   iterator       begin()       { return m_SectToExData.begin(); }
    120   const_iterator begin() const { return m_SectToExData.begin(); }
    121 
    122   /// end - return the iterator to the end of the map
    123   iterator       end()       { return m_SectToExData.end(); }
    124   const_iterator end() const { return m_SectToExData.end(); }
    125 
    126   /// erase - remove an entry from the map
    127   void erase(iterator it) { m_SectToExData.erase(it); }
    128 
    129  private:
    130   ARMInputExMap() = default;
    131 
    132  private:
    133   SectMap m_SectToExData;
    134 };
    135 
    136 /// ARMExData - ARM exception handling data of a mcld::Module.
    137 class ARMExData {
    138  private:
    139   typedef std::map<Input*, std::unique_ptr<ARMInputExMap> > InputMap;
    140 
    141   typedef std::map<const Fragment*, ARMExSectionTuple*> ExIdxMap;
    142 
    143  public:
    144   // create - Build the exception handling section mapping of a mcld::Module.
    145   static std::unique_ptr<ARMExData> create(Module &module);
    146 
    147   // addInputMap - register the ARMInputExMap with associated pInput
    148   void addInputMap(Input* pInput,
    149                    std::unique_ptr<ARMInputExMap> pExMap);
    150 
    151   // getInputMap - get the ARMInputExMap corresponding to pInput
    152   ARMInputExMap* getInputMap(Input* pInput) const {
    153     InputMap::const_iterator it = m_Inputs.find(pInput);
    154     if (it == m_Inputs.end()) {
    155       return NULL;
    156     }
    157     return it->second.get();
    158   }
    159 
    160   // getTupleByExIdx - get the ARMExSectionTuple corresponding to pExIdxFragment
    161   ARMExSectionTuple* getTupleByExIdx(const Fragment* pExIdxFragment) const {
    162     ExIdxMap::const_iterator it = m_ExIdxToTuple.find(pExIdxFragment);
    163     if (it == m_ExIdxToTuple.end()) {
    164       return NULL;
    165     }
    166     return it->second;
    167   }
    168 
    169  private:
    170   ARMExData() = default;
    171 
    172  private:
    173   // Map from Input to ARMInputExMap
    174   InputMap m_Inputs;
    175 
    176   // Map from .ARM.exidx RegionFragment to ARMExSectionTuple
    177   ExIdxMap m_ExIdxToTuple;
    178 };
    179 
    180 }  // namespace mcld
    181 
    182 #endif  // TARGET_ARM_ARMEXCEPTION_H_
    183