//===- EhFrame.cpp --------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/LD/EhFrame.h> #include <mcld/LD/LDSection.h> #include <mcld/LD/SectionData.h> #include <mcld/Object/ObjectBuilder.h> #include <mcld/Support/MemoryRegion.h> #include <mcld/Support/GCFactory.h> #include <llvm/Support/ManagedStatic.h> using namespace mcld; typedef GCFactory<EhFrame, MCLD_SECTIONS_PER_INPUT> EhFrameFactory; static llvm::ManagedStatic<EhFrameFactory> g_EhFrameFactory; //===----------------------------------------------------------------------===// // EhFrame::CIE //===----------------------------------------------------------------------===// EhFrame::CIE::CIE(MemoryRegion& pRegion) : RegionFragment(pRegion) { } //===----------------------------------------------------------------------===// // EhFrame::FDE //===----------------------------------------------------------------------===// EhFrame::FDE::FDE(MemoryRegion& pRegion, const EhFrame::CIE& pCIE, uint32_t pDataStart) : RegionFragment(pRegion), m_CIE(pCIE), m_DataStart(pDataStart) { } //===----------------------------------------------------------------------===// // EhFrame //===----------------------------------------------------------------------===// EhFrame::EhFrame() : m_pSection(NULL), m_pSectionData(NULL) { } EhFrame::EhFrame(LDSection& pSection) : m_pSection(&pSection), m_pSectionData(NULL) { m_pSectionData = SectionData::Create(pSection); } EhFrame::~EhFrame() { // Since all CIEs, FDEs and regular fragments are stored in iplist, iplist // will delete the fragments and we do not need to handle with it. } EhFrame* EhFrame::Create(LDSection& pSection) { EhFrame* result = g_EhFrameFactory->allocate(); new (result) EhFrame(pSection); return result; } void EhFrame::Destroy(EhFrame*& pSection) { pSection->~EhFrame(); g_EhFrameFactory->deallocate(pSection); pSection = NULL; } void EhFrame::Clear() { g_EhFrameFactory->clear(); } const LDSection& EhFrame::getSection() const { assert(NULL != m_pSection); return *m_pSection; } LDSection& EhFrame::getSection() { assert(NULL != m_pSection); return *m_pSection; } void EhFrame::addFragment(RegionFragment& pFrag) { uint32_t offset = 0; if (!m_pSectionData->empty()) offset = m_pSectionData->back().getOffset() + m_pSectionData->back().size(); m_pSectionData->getFragmentList().push_back(&pFrag); pFrag.setOffset(offset); } void EhFrame::addFragment(NullFragment& pFrag) { uint32_t offset = 0; if (!m_pSectionData->empty()) offset = m_pSectionData->back().getOffset() + m_pSectionData->back().size(); m_pSectionData->getFragmentList().push_back(&pFrag); pFrag.setOffset(offset); } void EhFrame::addCIE(EhFrame::CIE& pCIE) { m_CIEs.push_back(&pCIE); addFragment(pCIE); } void EhFrame::addFDE(EhFrame::FDE& pFDE) { m_FDEs.push_back(&pFDE); addFragment(pFDE); } EhFrame& EhFrame::merge(EhFrame& pOther) { ObjectBuilder::MoveSectionData(*pOther.getSectionData(), *m_pSectionData); m_CIEs.reserve(pOther.numOfCIEs() + m_CIEs.size()); for (cie_iterator cie = pOther.cie_begin(); cie != pOther.cie_end(); ++cie) m_CIEs.push_back(*cie); m_FDEs.reserve(pOther.numOfFDEs() + m_FDEs.size()); for (fde_iterator fde = pOther.fde_begin(); fde != pOther.fde_end(); ++fde) m_FDEs.push_back(*fde); pOther.m_CIEs.clear(); pOther.m_FDEs.clear(); return *this; }