EhFrame.h revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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
21namespace mcld {
22
23class LDSection;
24class SectionData;
25
26/** \class EhFrame
27 *  \brief EhFrame represents .eh_frame section
28 */
29class EhFrame
30{
31private:
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
42public:
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
91public:
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
144private:
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