Home | History | Annotate | Download | only in LD
      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