C++程序  |  145行  |  4.06 KB

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