C++程序  |  110行  |  2.84 KB

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