• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 using namespace mcld;
19 
20 typedef GCFactory<EhFrame, MCLD_SECTIONS_PER_INPUT> EhFrameFactory;
21 
22 static llvm::ManagedStatic<EhFrameFactory> g_EhFrameFactory;
23 
24 //===----------------------------------------------------------------------===//
25 // EhFrame::CIE
26 //===----------------------------------------------------------------------===//
CIE(MemoryRegion & pRegion)27 EhFrame::CIE::CIE(MemoryRegion& pRegion)
28   : RegionFragment(pRegion) {
29 }
30 
31 //===----------------------------------------------------------------------===//
32 // EhFrame::FDE
33 //===----------------------------------------------------------------------===//
FDE(MemoryRegion & pRegion,const EhFrame::CIE & pCIE,uint32_t pDataStart)34 EhFrame::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 //===----------------------------------------------------------------------===//
EhFrame()45 EhFrame::EhFrame()
46   : m_pSection(NULL), m_pSectionData(NULL) {
47 }
48 
EhFrame(LDSection & pSection)49 EhFrame::EhFrame(LDSection& pSection)
50   : m_pSection(&pSection),
51     m_pSectionData(NULL) {
52   m_pSectionData = SectionData::Create(pSection);
53 }
54 
~EhFrame()55 EhFrame::~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 
Create(LDSection & pSection)61 EhFrame* EhFrame::Create(LDSection& pSection)
62 {
63   EhFrame* result = g_EhFrameFactory->allocate();
64   new (result) EhFrame(pSection);
65   return result;
66 }
67 
Destroy(EhFrame * & pSection)68 void EhFrame::Destroy(EhFrame*& pSection)
69 {
70   pSection->~EhFrame();
71   g_EhFrameFactory->deallocate(pSection);
72   pSection = NULL;
73 }
74 
Clear()75 void EhFrame::Clear()
76 {
77   g_EhFrameFactory->clear();
78 }
79 
getSection() const80 const LDSection& EhFrame::getSection() const
81 {
82   assert(NULL != m_pSection);
83   return *m_pSection;
84 }
85 
getSection()86 LDSection& EhFrame::getSection()
87 {
88   assert(NULL != m_pSection);
89   return *m_pSection;
90 }
91 
addFragment(RegionFragment & pFrag)92 void 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 
addCIE(EhFrame::CIE & pCIE)102 void EhFrame::addCIE(EhFrame::CIE& pCIE)
103 {
104   m_CIEs.push_back(&pCIE);
105   addFragment(pCIE);
106 }
107 
addFDE(EhFrame::FDE & pFDE)108 void EhFrame::addFDE(EhFrame::FDE& pFDE)
109 {
110   m_FDEs.push_back(&pFDE);
111   addFragment(pFDE);
112 }
113 
merge(EhFrame & pOther)114 EhFrame& EhFrame::merge(EhFrame& pOther)
115 {
116   ObjectBuilder::MoveSectionData(pOther.getSectionData(), *m_pSectionData);
117 
118   m_CIEs.reserve(pOther.numOfCIEs() + m_CIEs.size());
119   for (cie_iterator cie = pOther.cie_begin(); cie != pOther.cie_end(); ++cie)
120     m_CIEs.push_back(*cie);
121 
122   m_FDEs.reserve(pOther.numOfFDEs() + m_FDEs.size());
123   for (fde_iterator fde = pOther.fde_begin(); fde != pOther.fde_end(); ++fde)
124     m_FDEs.push_back(*fde);
125 
126   pOther.m_CIEs.clear();
127   pOther.m_FDEs.clear();
128   return *this;
129 }
130 
131