//===- ARMException.h -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef TARGET_ARM_ARMEXCEPTION_H_ #define TARGET_ARM_ARMEXCEPTION_H_ #include "mcld/LD/LDSection.h" #include <llvm/ADT/PointerUnion.h> #include <llvm/ADT/StringRef.h> #include <llvm/Support/ELF.h> #include <map> #include <memory> #include <string> namespace mcld { class Fragment; class Input; class LDSection; class Module; class RegionFragment; class RelocData; /// ARMExSectionTuple - Tuple of associated exception handling sections class ARMExSectionTuple { public: ARMExSectionTuple() : m_pTextSection(NULL), m_pExIdxSection(NULL) { } LDSection* getTextSection() const { return m_pTextSection; } LDSection* getExIdxSection() const { return m_pExIdxSection; } void setTextSection(LDSection* pSection) { m_pTextSection = pSection; } void setExIdxSection(LDSection* pSection) { m_pExIdxSection = pSection; } RegionFragment* getTextFragment() const { return m_pTextFragment; } RegionFragment* getExIdxFragment() const { return m_pExIdxFragment; } void setTextFragment(RegionFragment* pFragment) { m_pTextFragment = pFragment; } void setExIdxFragment(RegionFragment* pFragment) { m_pExIdxFragment = pFragment; } private: // .text section union { LDSection* m_pTextSection; RegionFragment* m_pTextFragment; }; // .ARM.exidx section union { LDSection* m_pExIdxSection; RegionFragment* m_pExIdxFragment; }; }; /// ARMInputExMap - ARM exception handling section mapping of a mcld::Input. class ARMInputExMap { public: typedef std::map<LDSection*, std::unique_ptr<ARMExSectionTuple> > SectMap; typedef SectMap::iterator iterator; typedef SectMap::const_iterator const_iterator; public: // create - Build the exception handling section mapping of a mcld::Input. static std::unique_ptr<ARMInputExMap> create(Input &input); /// getByExSection - Get the ARMExSectionTuple by the address of the /// .ARM.exidx section. ARMExSectionTuple* getByExSection(LDSection &pSect) const { assert(pSect.type() == llvm::ELF::SHT_ARM_EXIDX); SectMap::const_iterator it = m_SectToExData.find(&pSect); if (it == m_SectToExData.end()) { return NULL; } return it->second.get(); } /// getOrCreate - Get an existing or create a new ARMExSectionTuple which is /// associated with the address of the .ARM.exidx section. ARMExSectionTuple* getOrCreateByExSection(LDSection &pSect) { assert(pSect.type() == llvm::ELF::SHT_ARM_EXIDX); std::unique_ptr<ARMExSectionTuple>& result = m_SectToExData[&pSect]; if (!result) { result.reset(new ARMExSectionTuple()); } return result.get(); } /// begin - return the iterator to the begin of the map iterator begin() { return m_SectToExData.begin(); } const_iterator begin() const { return m_SectToExData.begin(); } /// end - return the iterator to the end of the map iterator end() { return m_SectToExData.end(); } const_iterator end() const { return m_SectToExData.end(); } /// erase - remove an entry from the map void erase(iterator it) { m_SectToExData.erase(it); } private: ARMInputExMap() = default; private: SectMap m_SectToExData; }; /// ARMExData - ARM exception handling data of a mcld::Module. class ARMExData { private: typedef std::map<Input*, std::unique_ptr<ARMInputExMap> > InputMap; typedef std::map<const Fragment*, ARMExSectionTuple*> ExIdxMap; public: // create - Build the exception handling section mapping of a mcld::Module. static std::unique_ptr<ARMExData> create(Module &module); // addInputMap - register the ARMInputExMap with associated pInput void addInputMap(Input* pInput, std::unique_ptr<ARMInputExMap> pExMap); // getInputMap - get the ARMInputExMap corresponding to pInput ARMInputExMap* getInputMap(Input* pInput) const { InputMap::const_iterator it = m_Inputs.find(pInput); if (it == m_Inputs.end()) { return NULL; } return it->second.get(); } // getTupleByExIdx - get the ARMExSectionTuple corresponding to pExIdxFragment ARMExSectionTuple* getTupleByExIdx(const Fragment* pExIdxFragment) const { ExIdxMap::const_iterator it = m_ExIdxToTuple.find(pExIdxFragment); if (it == m_ExIdxToTuple.end()) { return NULL; } return it->second; } private: ARMExData() = default; private: // Map from Input to ARMInputExMap InputMap m_Inputs; // Map from .ARM.exidx RegionFragment to ARMExSectionTuple ExIdxMap m_ExIdxToTuple; }; } // namespace mcld #endif // TARGET_ARM_ARMEXCEPTION_H_