| //===- 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_ |