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 //===----------------------------------------------------------------------===// 27 EhFrame::CIE::CIE(MemoryRegion& pRegion) 28 : RegionFragment(pRegion) { 29 } 30 31 //===----------------------------------------------------------------------===// 32 // EhFrame::FDE 33 //===----------------------------------------------------------------------===// 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 //===----------------------------------------------------------------------===// 45 EhFrame::EhFrame() 46 : m_pSection(NULL), m_pSectionData(NULL) { 47 } 48 49 EhFrame::EhFrame(LDSection& pSection) 50 : m_pSection(&pSection), 51 m_pSectionData(NULL) { 52 m_pSectionData = SectionData::Create(pSection); 53 } 54 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 61 EhFrame* EhFrame::Create(LDSection& pSection) 62 { 63 EhFrame* result = g_EhFrameFactory->allocate(); 64 new (result) EhFrame(pSection); 65 return result; 66 } 67 68 void EhFrame::Destroy(EhFrame*& pSection) 69 { 70 pSection->~EhFrame(); 71 g_EhFrameFactory->deallocate(pSection); 72 pSection = NULL; 73 } 74 75 void EhFrame::Clear() 76 { 77 g_EhFrameFactory->clear(); 78 } 79 80 const LDSection& EhFrame::getSection() const 81 { 82 assert(NULL != m_pSection); 83 return *m_pSection; 84 } 85 86 LDSection& EhFrame::getSection() 87 { 88 assert(NULL != m_pSection); 89 return *m_pSection; 90 } 91 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 102 void 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 112 void EhFrame::addCIE(EhFrame::CIE& pCIE) 113 { 114 m_CIEs.push_back(&pCIE); 115 addFragment(pCIE); 116 } 117 118 void EhFrame::addFDE(EhFrame::FDE& pFDE) 119 { 120 m_FDEs.push_back(&pFDE); 121 addFragment(pFDE); 122 } 123 124 EhFrame& 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