Home | History | Annotate | Download | only in LD
      1 //===- EhFrame.h ----------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #ifndef MCLD_LD_EH_FRAME_H
     10 #define MCLD_LD_EH_FRAME_H
     11 #ifdef ENABLE_UNITTEST
     12 #include <gtest.h>
     13 #endif
     14 
     15 #include <mcld/Config/Config.h>
     16 #include <mcld/Fragment/RegionFragment.h>
     17 #include <mcld/Support/Allocators.h>
     18 
     19 #include <vector>
     20 
     21 namespace mcld {
     22 
     23 class LDSection;
     24 class SectionData;
     25 
     26 /** \class EhFrame
     27  *  \brief EhFrame represents .eh_frame section
     28  */
     29 class EhFrame
     30 {
     31 private:
     32   friend class Chunk<EhFrame, MCLD_SECTIONS_PER_INPUT>;
     33 
     34   EhFrame();
     35   explicit EhFrame(LDSection& pSection);
     36 
     37   ~EhFrame();
     38 
     39   EhFrame(const EhFrame&);            // DO NOT IMPLEMENT
     40   EhFrame& operator=(const EhFrame&); // DO NOT IMPLEMENT
     41 
     42 public:
     43   /** \class CIE
     44    *  \brief Common Information Entry.
     45    *  The CIE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
     46    */
     47   class CIE : public RegionFragment
     48   {
     49   public:
     50     CIE(MemoryRegion& pRegion);
     51 
     52     void setFDEEncode(uint8_t pEncode) { m_FDEEncode = pEncode; }
     53     uint8_t getFDEEncode() const { return m_FDEEncode; }
     54 
     55   private:
     56     uint8_t m_FDEEncode;
     57   };
     58 
     59   /** \class FDE
     60    *  \brief Frame Description Entry
     61    *  The FDE structure refers to LSB Core Spec 4.1, chap.10.6. Exception Frames.
     62    */
     63   class FDE : public RegionFragment
     64   {
     65   public:
     66     FDE(MemoryRegion& pRegion,
     67         const CIE& pCIE,
     68         uint32_t pDataStart);
     69 
     70     const CIE& getCIE() const { return m_CIE; }
     71 
     72     uint32_t getDataStart() const { return m_DataStart; }
     73 
     74   private:
     75     const CIE& m_CIE;
     76     uint32_t m_DataStart;
     77   };
     78 
     79   typedef std::vector<CIE*> CIEList;
     80 
     81   // cie_iterator and const_cie_iterator must be a kind of random access iterator
     82   typedef CIEList::iterator cie_iterator;
     83   typedef CIEList::const_iterator const_cie_iterator;
     84 
     85   typedef std::vector<FDE*> FDEList;
     86 
     87   // fde_iterator and const_fde_iterator must be a kind of random access iterator
     88   typedef FDEList::iterator fde_iterator;
     89   typedef FDEList::const_iterator const_fde_iterator;
     90 
     91 public:
     92   static EhFrame* Create(LDSection& pSection);
     93 
     94   static void Destroy(EhFrame*& pSection);
     95 
     96   static void Clear();
     97 
     98   /// merge - move all data from pOther to this object.
     99   EhFrame& merge(EhFrame& pOther);
    100 
    101   const LDSection& getSection() const;
    102   LDSection&       getSection();
    103 
    104   const SectionData& getSectionData() const { return *m_pSectionData; }
    105   SectionData&       getSectionData()       { return *m_pSectionData; }
    106 
    107   // -----  fragment  ----- //
    108   /// addFragment - when we start treating CIEs and FDEs as regular fragments,
    109   /// we call this function instead of addCIE() and addFDE().
    110   void addFragment(RegionFragment& pFrag);
    111 
    112   /// addCIE - add a CIE entry in EhFrame
    113   void addCIE(CIE& pCIE);
    114 
    115   /// addFDE - add a FDE entry in EhFrame
    116   void addFDE(FDE& pFDE);
    117 
    118   // -----  CIE  ----- //
    119   const_cie_iterator cie_begin() const { return m_CIEs.begin(); }
    120   cie_iterator       cie_begin()       { return m_CIEs.begin(); }
    121   const_cie_iterator cie_end  () const { return m_CIEs.end(); }
    122   cie_iterator       cie_end  ()       { return m_CIEs.end(); }
    123 
    124   const CIE& cie_front() const { return *m_CIEs.front(); }
    125   CIE&       cie_front()       { return *m_CIEs.front(); }
    126   const CIE& cie_back () const { return *m_CIEs.back(); }
    127   CIE&       cie_back ()       { return *m_CIEs.back(); }
    128 
    129   size_t numOfCIEs() const { return m_CIEs.size(); }
    130 
    131   // -----  FDE  ----- //
    132   const_fde_iterator fde_begin() const { return m_FDEs.begin(); }
    133   fde_iterator       fde_begin()       { return m_FDEs.begin(); }
    134   const_fde_iterator fde_end  () const { return m_FDEs.end(); }
    135   fde_iterator       fde_end  ()       { return m_FDEs.end(); }
    136 
    137   const FDE& fde_front() const { return *m_FDEs.front(); }
    138   FDE&       fde_front()       { return *m_FDEs.front(); }
    139   const FDE& fde_back () const { return *m_FDEs.back(); }
    140   FDE&       fde_back ()       { return *m_FDEs.back(); }
    141 
    142   size_t numOfFDEs() const { return m_FDEs.size(); }
    143 
    144 private:
    145   LDSection* m_pSection;
    146   SectionData* m_pSectionData;
    147 
    148   CIEList m_CIEs;
    149   FDEList m_FDEs;
    150 };
    151 
    152 } // namespace of mcld
    153 
    154 #endif
    155 
    156