//===- 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/LD/RegionFragment.h> #include <mcld/Support/GCFactory.h> namespace mcld { class Input; class Layout; class SectionData; class TargetLDBackend; /** \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 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 SectionData 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, SectionData& pSD, const Input& pInput, 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<Fragment*> 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 Fragments in pList void deleteFragments(FragListType& pList, MemoryArea& pArea); private: CIEListType m_CIEs; FDEListType m_FDEs; bool m_fCanRecognizeAll; }; } // namespace of mcld #endif