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