//===- BranchIsland.cpp ---------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/BranchIsland.h>
#include <mcld/LD/ResolveInfo.h>
#include <mcld/LD/LDSection.h>
#include <mcld/Fragment/Stub.h>
#include <mcld/Fragment/AlignFragment.h>

#include <sstream>

using namespace mcld;

//==========================
// BranchIsland

BranchIsland::BranchIsland(Fragment& pEntryFrag,
                           size_t pMaxSize,
                           size_t pIndex)
 : m_Entry(pEntryFrag),
   m_pExit(pEntryFrag.getNextNode()),
   m_pRear(NULL),
   m_MaxSize(pMaxSize),
   m_Name("island-")
{
  // island name
  std::ostringstream index;
  index << pIndex;
  m_Name.append(index.str());
}

BranchIsland::~BranchIsland()
{
}

/// fragment iterators of the island
SectionData::iterator BranchIsland::begin()
{
  return ++iterator(&m_Entry);
}

SectionData::const_iterator BranchIsland::begin() const
{
  return ++iterator(&m_Entry);
}

SectionData::iterator BranchIsland::end()
{
  if (NULL != m_pExit)
    return iterator(m_pExit);
  return m_Entry.getParent()->end();
}

SectionData::const_iterator BranchIsland::end() const
{
  if (NULL != m_pExit)
    return iterator(m_pExit);
  return m_Entry.getParent()->end();
}

uint64_t BranchIsland::offset() const
{
  return m_Entry.getOffset() + m_Entry.size();
}

size_t BranchIsland::size() const
{
  size_t size = 0x0;
  if (0x0 != numOfStubs()) {
    size = m_pRear->getOffset() + m_pRear->size() -
           m_Entry.getNextNode()->getOffset();
  }
  return size;
}

size_t BranchIsland::maxSize() const
{
  return m_MaxSize;
}

const std::string& BranchIsland::name() const
{
  return m_Name;
}

size_t BranchIsland::numOfStubs() const
{
  return m_StubMap.numOfEntries();
}

/// findStub - return true if there is a stub built from the given prototype
///            for the given relocation
Stub* BranchIsland::findStub(const Stub* pPrototype, const Relocation& pReloc)
{
  Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
  StubMapType::iterator it = m_StubMap.find(key);
  if (it != m_StubMap.end()) {
    assert(NULL != it.getEntry()->value());
    return it.getEntry()->value();
  }
  return NULL;
}

/// addStub - add a stub into the island
bool BranchIsland::addStub(const Stub* pPrototype,
                           const Relocation& pReloc,
                           Stub& pStub)
{
  bool exist = false;
  Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
  StubEntryType* entry = m_StubMap.insert(key, exist);
  if (!exist) {
    entry->setValue(&pStub);
    m_pRear = &pStub;
    SectionData* sd = m_Entry.getParent();

    // insert alignment fragment
    // TODO: check if we can reduce this alignment fragment for some cases
    AlignFragment* align_frag = new AlignFragment(pStub.alignment(),
                                                  0x0,
                                                  1u,
                                                  pStub.alignment() - 1);
    align_frag->setParent(sd);
    sd->getFragmentList().insert(end(), align_frag);
    align_frag->setOffset(align_frag->getPrevNode()->getOffset() +
                          align_frag->getPrevNode()->size());

    // insert stub fragment
    pStub.setParent(sd);
    sd->getFragmentList().insert(end(), &pStub);
    pStub.setOffset(pStub.getPrevNode()->getOffset() +
                    pStub.getPrevNode()->size());
  }
  return !exist;
}

/// addRelocation - add a relocation into island
bool BranchIsland::addRelocation(Relocation& pReloc)
{
  m_Relocations.push_back(&pReloc);
  return true;
}

