EhFrame.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
1//===- EhFrame.cpp --------------------------------------------------------===//
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#include <mcld/LD/EhFrame.h>
10#include <mcld/LD/LDSection.h>
11#include <mcld/LD/SectionData.h>
12#include <mcld/Object/ObjectBuilder.h>
13#include <mcld/Support/MemoryRegion.h>
14#include <mcld/Support/GCFactory.h>
15
16#include <llvm/Support/ManagedStatic.h>
17
18using namespace mcld;
19
20typedef GCFactory<EhFrame, MCLD_SECTIONS_PER_INPUT> EhFrameFactory;
21
22static llvm::ManagedStatic<EhFrameFactory> g_EhFrameFactory;
23
24//===----------------------------------------------------------------------===//
25// EhFrame::CIE
26//===----------------------------------------------------------------------===//
27EhFrame::CIE::CIE(MemoryRegion& pRegion)
28  : RegionFragment(pRegion) {
29}
30
31//===----------------------------------------------------------------------===//
32// EhFrame::FDE
33//===----------------------------------------------------------------------===//
34EhFrame::FDE::FDE(MemoryRegion& pRegion,
35                  const EhFrame::CIE& pCIE,
36                  uint32_t pDataStart)
37  : RegionFragment(pRegion),
38    m_CIE(pCIE),
39    m_DataStart(pDataStart) {
40}
41
42//===----------------------------------------------------------------------===//
43// EhFrame
44//===----------------------------------------------------------------------===//
45EhFrame::EhFrame()
46  : m_pSection(NULL), m_pSectionData(NULL) {
47}
48
49EhFrame::EhFrame(LDSection& pSection)
50  : m_pSection(&pSection),
51    m_pSectionData(NULL) {
52  m_pSectionData = SectionData::Create(pSection);
53}
54
55EhFrame::~EhFrame()
56{
57  // Since all CIEs, FDEs and regular fragments are stored in iplist, iplist
58  // will delete the fragments and we do not need to handle with it.
59}
60
61EhFrame* EhFrame::Create(LDSection& pSection)
62{
63  EhFrame* result = g_EhFrameFactory->allocate();
64  new (result) EhFrame(pSection);
65  return result;
66}
67
68void EhFrame::Destroy(EhFrame*& pSection)
69{
70  pSection->~EhFrame();
71  g_EhFrameFactory->deallocate(pSection);
72  pSection = NULL;
73}
74
75void EhFrame::Clear()
76{
77  g_EhFrameFactory->clear();
78}
79
80const LDSection& EhFrame::getSection() const
81{
82  assert(NULL != m_pSection);
83  return *m_pSection;
84}
85
86LDSection& EhFrame::getSection()
87{
88  assert(NULL != m_pSection);
89  return *m_pSection;
90}
91
92void EhFrame::addFragment(RegionFragment& pFrag)
93{
94  uint32_t offset = 0;
95  if (!m_pSectionData->empty())
96    offset = m_pSectionData->back().getOffset() + m_pSectionData->back().size();
97
98  m_pSectionData->getFragmentList().push_back(&pFrag);
99  pFrag.setOffset(offset);
100}
101
102void EhFrame::addFragment(NullFragment& pFrag)
103{
104  uint32_t offset = 0;
105  if (!m_pSectionData->empty())
106    offset = m_pSectionData->back().getOffset() + m_pSectionData->back().size();
107
108  m_pSectionData->getFragmentList().push_back(&pFrag);
109  pFrag.setOffset(offset);
110}
111
112void EhFrame::addCIE(EhFrame::CIE& pCIE)
113{
114  m_CIEs.push_back(&pCIE);
115  addFragment(pCIE);
116}
117
118void EhFrame::addFDE(EhFrame::FDE& pFDE)
119{
120  m_FDEs.push_back(&pFDE);
121  addFragment(pFDE);
122}
123
124EhFrame& EhFrame::merge(EhFrame& pOther)
125{
126  ObjectBuilder::MoveSectionData(*pOther.getSectionData(), *m_pSectionData);
127
128  m_CIEs.reserve(pOther.numOfCIEs() + m_CIEs.size());
129  for (cie_iterator cie = pOther.cie_begin(); cie != pOther.cie_end(); ++cie)
130    m_CIEs.push_back(*cie);
131
132  m_FDEs.reserve(pOther.numOfFDEs() + m_FDEs.size());
133  for (fde_iterator fde = pOther.fde_begin(); fde != pOther.fde_end(); ++fde)
134    m_FDEs.push_back(*fde);
135
136  pOther.m_CIEs.clear();
137  pOther.m_FDEs.clear();
138  return *this;
139}
140
141