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: ARMExSectionTuple()34 ARMExSectionTuple() 35 : m_pTextSection(NULL), 36 m_pExIdxSection(NULL) { 37 } 38 getTextSection()39 LDSection* getTextSection() const { 40 return m_pTextSection; 41 } 42 getExIdxSection()43 LDSection* getExIdxSection() const { 44 return m_pExIdxSection; 45 } 46 setTextSection(LDSection * pSection)47 void setTextSection(LDSection* pSection) { 48 m_pTextSection = pSection; 49 } 50 setExIdxSection(LDSection * pSection)51 void setExIdxSection(LDSection* pSection) { 52 m_pExIdxSection = pSection; 53 } 54 getTextFragment()55 RegionFragment* getTextFragment() const { 56 return m_pTextFragment; 57 } 58 getExIdxFragment()59 RegionFragment* getExIdxFragment() const { 60 return m_pExIdxFragment; 61 } 62 setTextFragment(RegionFragment * pFragment)63 void setTextFragment(RegionFragment* pFragment) { 64 m_pTextFragment = pFragment; 65 } 66 setExIdxFragment(RegionFragment * pFragment)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. getByExSection(LDSection & pSect)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. getOrCreateByExSection(LDSection & pSect)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 begin()119 iterator begin() { return m_SectToExData.begin(); } begin()120 const_iterator begin() const { return m_SectToExData.begin(); } 121 122 /// end - return the iterator to the end of the map end()123 iterator end() { return m_SectToExData.end(); } end()124 const_iterator end() const { return m_SectToExData.end(); } 125 126 /// erase - remove an entry from the map erase(iterator it)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 getInputMap(Input * 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 getTupleByExIdx(const Fragment * 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