| //===- 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/Support/MemoryRegion.h> |
| #include <mcld/Object/ObjectBuilder.h> |
| |
| using namespace mcld; |
| |
| //===----------------------------------------------------------------------===// |
| // 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(LDSection& pSection) |
| : m_Section(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. |
| } |
| |
| 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::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; |
| } |
| |