blob: df61c24fa2088d8c31487c5c434336a1d8fe93d9 [file] [log] [blame]
//===- 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;
}