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