| //===- EhFrame.h ----------------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef MCLD_EXCEPTION_HANDLING_FRAME_H |
| #define MCLD_EXCEPTION_HANDLING_FRAME_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| #include <vector> |
| |
| #include <mcld/ADT/TypeTraits.h> |
| #include <mcld/LD/CIE.h> |
| #include <mcld/LD/FDE.h> |
| #include <mcld/MC/MCRegionFragment.h> |
| #include <mcld/Support/GCFactory.h> |
| |
| namespace mcld |
| { |
| /** \class EhFrame |
| * \brief EhFrame represents .eh_frame section |
| * EhFrame is responsible to parse the input eh_frame sections and create |
| * the corresponding CIE and FDE entries. |
| */ |
| |
| class TargetLDBackend; |
| |
| class EhFrame |
| { |
| public: |
| typedef ConstTraits<unsigned char>::pointer ConstAddress; |
| typedef std::vector<CIE*> CIEListType; |
| typedef std::vector<FDE*> FDEListType; |
| typedef CIEListType::iterator cie_iterator; |
| typedef CIEListType::const_iterator const_cie_iterator; |
| typedef FDEListType::iterator fde_iterator; |
| typedef FDEListType::const_iterator const_fde_iterator; |
| |
| public: |
| EhFrame(); |
| ~EhFrame(); |
| |
| /// readEhFrame - read an .eh_frame section and create the corresponding |
| /// CIEs and FDEs |
| /// @param pSD - the MCSectionData of this input eh_frame |
| /// @param pSection - the input eh_frame |
| /// @param pArea - the memory area which pSection is within. |
| /// @ return - size of this eh_frame section, 0 if we do not recognize |
| /// this eh_frame or this is an empty section |
| uint64_t readEhFrame(Layout& pLayout, |
| const TargetLDBackend& pBackend, |
| llvm::MCSectionData& pSD, |
| LDSection& pSection, |
| MemoryArea& pArea); |
| |
| // ----- observers ----- // |
| cie_iterator cie_begin() |
| { return m_CIEs.begin(); } |
| |
| const_cie_iterator cie_begin() const |
| { return m_CIEs.begin(); } |
| |
| cie_iterator cie_end() |
| { return m_CIEs.end(); } |
| |
| const_cie_iterator cie_end() const |
| { return m_CIEs.end(); } |
| |
| fde_iterator fde_begin() |
| { return m_FDEs.begin(); } |
| |
| const_fde_iterator fde_begin() const |
| { return m_FDEs.begin(); } |
| |
| fde_iterator fde_end() |
| { return m_FDEs.end(); } |
| |
| const_fde_iterator fde_end() const |
| { return m_FDEs.end(); } |
| |
| /// getFDECount - the number of FDE entries |
| size_t getFDECount() |
| { return m_FDEs.size(); } |
| |
| size_t getFDECount() const |
| { return m_FDEs.size(); } |
| |
| /// canRecognizeAllEhFrame - return if we are able to parse all input |
| /// eh_frame sections |
| /// @return false - if there is any input .eh_frame section that |
| /// we are not able to recognize |
| bool canRecognizeAllEhFrame() |
| { return m_fCanRecognizeAll; } |
| |
| bool canRecognizeAllEhFrame() const |
| { return m_fCanRecognizeAll; } |
| |
| private: |
| typedef std::vector<llvm::MCFragment*> FragListType; |
| |
| private: |
| /// addCIE - parse and create a CIE entry |
| /// @return false - cannot recognize this CIE |
| bool addCIE(MemoryRegion& pFrag, |
| const TargetLDBackend& pBackend, |
| FragListType& pFragList); |
| |
| /// addFDE - parse and create an FDE entry |
| /// @return false - cannot recognize this FDE |
| bool addFDE(MemoryRegion& pFrag, |
| const TargetLDBackend& pBackend, |
| FragListType& pFragList); |
| |
| /// readVal - read a 32 bit data from pAddr, swap it if needed |
| uint32_t readVal(ConstAddress pAddr, bool pIsTargetLittleEndian); |
| |
| /// skipLEB128 - skip the first LEB128 encoded value from *pp, update *pp |
| /// to the next character. |
| /// @return - false if we ran off the end of the string. |
| /// @ref - GNU gold 1.11, ehframe.h, Eh_frame::skip_leb128. |
| bool skipLEB128(ConstAddress* pp, ConstAddress pend); |
| |
| /// deleteFragments - release the MemoryRegion and delete MCFragments in pList |
| void deleteFragments(FragListType& pList, MemoryArea& pArea); |
| |
| private: |
| CIEListType m_CIEs; |
| FDEListType m_FDEs; |
| |
| bool m_fCanRecognizeAll; |
| }; |
| |
| } // namespace of mcld |
| |
| #endif |
| |