EhFrame.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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::addCIE(EhFrame::CIE& pCIE) 103{ 104 m_CIEs.push_back(&pCIE); 105 addFragment(pCIE); 106} 107 108void EhFrame::addFDE(EhFrame::FDE& pFDE) 109{ 110 m_FDEs.push_back(&pFDE); 111 addFragment(pFDE); 112} 113 114EhFrame& 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