//===- EhFrameReader.h ----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_EH_FRAME_READER_H #define MCLD_EH_FRAME_READER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <mcld/Support/MemoryRegion.h> namespace mcld { class Input; class EhFrame; class LDSection; /** \class EhFrameReader * \brief EhFrameReader reads .eh_frame section * * EhFrameReader is responsible to parse the input eh_frame sections and create * the corresponding CIE and FDE entries. */ class EhFrameReader { public: typedef const uint8_t* ConstAddress; typedef uint8_t* Address; public: /// read - read an .eh_frame section and create the corresponding /// CIEs and FDEs /// @param pInput [in] the Input contains this eh_frame /// @param pEhFrame [inout] the input eh_frame /// @return if we read all CIEs and FDEs successfully, return true. Otherwise, /// return false; template<size_t BITCLASS, bool SAME_ENDIAN> bool read(Input& pInput, EhFrame& pEhFrame); private: enum TokenKind { CIE, FDE, Terminator, Unknown, NumOfTokenKinds }; enum State { Q0, Q1, Accept, NumOfStates = 2, Reject = -1 }; struct Token { TokenKind kind; size_t file_off; size_t data_off; uint64_t size; }; /// Action - the transition function of autometa. /// @param pEhFrame - the output .eh_frame section /// @param pSection - the input .eh_frame section /// @param pRegion - the memory region that needs to handle with. typedef bool (*Action)(EhFrame& pEhFrame, MemoryRegion& pRegion, const Token& pToken); private: /// scan - scan pData from pHandler for a token. template<bool SAME_ENDIAN> Token scan(ConstAddress pHandler, uint64_t pOffset, const MemoryRegion& pData) const; static bool addCIE(EhFrame& pEhFrame, MemoryRegion& pRegion, const Token& pToken); static bool addFDE(EhFrame& pEhFrame, MemoryRegion& pRegion, const Token& pToken); static bool addTerm(EhFrame& pEhFrame, MemoryRegion& pRegion, const Token& pToken); static bool reject(EhFrame& pEhFrame, MemoryRegion& pRegion, const Token& pToken); }; template<> bool EhFrameReader::read<32, true>(Input& pInput, EhFrame& pEhFrame); template<> EhFrameReader::Token EhFrameReader::scan<true>(ConstAddress pHandler, uint64_t pOffset, const MemoryRegion& pData) const; } // namespace of mcld #endif