EhFrame.h revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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
22namespace mcld {
23
24class LDSection;
25class SectionData;
26
27/** \class EhFrame
28 *  \brief EhFrame represents .eh_frame section
29 */
30class EhFrame
31{
32private:
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
43public:
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
92public:
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
147private:
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