• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setFDEEncode(uint8_t pEncode)53     void setFDEEncode(uint8_t pEncode) { m_FDEEncode = pEncode; }
getFDEEncode()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 
getCIE()71     const CIE& getCIE() const { return m_CIE; }
72 
getDataStart()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 
getSectionData()105   const SectionData* getSectionData() const { return m_pSectionData; }
getSectionData()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  ----- //
cie_begin()122   const_cie_iterator cie_begin() const { return m_CIEs.begin(); }
cie_begin()123   cie_iterator       cie_begin()       { return m_CIEs.begin(); }
cie_end()124   const_cie_iterator cie_end  () const { return m_CIEs.end(); }
cie_end()125   cie_iterator       cie_end  ()       { return m_CIEs.end(); }
126 
cie_front()127   const CIE& cie_front() const { return *m_CIEs.front(); }
cie_front()128   CIE&       cie_front()       { return *m_CIEs.front(); }
cie_back()129   const CIE& cie_back () const { return *m_CIEs.back(); }
cie_back()130   CIE&       cie_back ()       { return *m_CIEs.back(); }
131 
numOfCIEs()132   size_t numOfCIEs() const { return m_CIEs.size(); }
133 
134   // -----  FDE  ----- //
fde_begin()135   const_fde_iterator fde_begin() const { return m_FDEs.begin(); }
fde_begin()136   fde_iterator       fde_begin()       { return m_FDEs.begin(); }
fde_end()137   const_fde_iterator fde_end  () const { return m_FDEs.end(); }
fde_end()138   fde_iterator       fde_end  ()       { return m_FDEs.end(); }
139 
fde_front()140   const FDE& fde_front() const { return *m_FDEs.front(); }
fde_front()141   FDE&       fde_front()       { return *m_FDEs.front(); }
fde_back()142   const FDE& fde_back () const { return *m_FDEs.back(); }
fde_back()143   FDE&       fde_back ()       { return *m_FDEs.back(); }
144 
numOfFDEs()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