15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- BranchIsland.cpp ---------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIsland.h>
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Stub.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/AlignFragment.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <sstream>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//==========================
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// BranchIsland
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoBranchIsland::BranchIsland(Fragment& pEntryFrag,
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           size_t pMaxSize,
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           size_t pIndex)
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_Entry(pEntryFrag),
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   m_pExit(pEntryFrag.getNextNode()),
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   m_pRear(NULL),
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   m_MaxSize(pMaxSize),
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao   m_Name("island-")
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // island name
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::ostringstream index;
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  index << pIndex;
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_Name.append(index.str());
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoBranchIsland::~BranchIsland()
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// fragment iterators of the island
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData::iterator BranchIsland::begin()
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return ++iterator(&m_Entry);
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData::const_iterator BranchIsland::begin() const
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return ++iterator(&m_Entry);
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData::iterator BranchIsland::end()
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != m_pExit)
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return iterator(m_pExit);
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Entry.getParent()->end();
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData::const_iterator BranchIsland::end() const
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL != m_pExit)
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return iterator(m_pExit);
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Entry.getParent()->end();
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t BranchIsland::offset() const
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Entry.getOffset() + m_Entry.size();
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t BranchIsland::size() const
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t size = 0x0;
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0x0 != numOfStubs()) {
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    size = m_pRear->getOffset() + m_pRear->size() -
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao           m_Entry.getNextNode()->getOffset();
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t BranchIsland::maxSize() const
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_MaxSize;
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoconst std::string& BranchIsland::name() const
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_Name;
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t BranchIsland::numOfStubs() const
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return m_StubMap.numOfEntries();
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// findStub - return true if there is a stub built from the given prototype
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao///            for the given relocation
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoStub* BranchIsland::findStub(const Stub* pPrototype, const Relocation& pReloc)
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubMapType::iterator it = m_StubMap.find(key);
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (it != m_StubMap.end()) {
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    assert(NULL != it.getEntry()->value());
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return it.getEntry()->value();
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return NULL;
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addStub - add a stub into the island
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool BranchIsland::addStub(const Stub* pPrototype,
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           const Relocation& pReloc,
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                           Stub& pStub)
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool exist = false;
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubEntryType* entry = m_StubMap.insert(key, exist);
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!exist) {
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    entry->setValue(&pStub);
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pRear = &pStub;
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    SectionData* sd = m_Entry.getParent();
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // insert alignment fragment
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // TODO: check if we can reduce this alignment fragment for some cases
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    AlignFragment* align_frag = new AlignFragment(pStub.alignment(),
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  0x0,
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  1u,
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                  pStub.alignment() - 1);
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    align_frag->setParent(sd);
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    sd->getFragmentList().insert(end(), align_frag);
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    align_frag->setOffset(align_frag->getPrevNode()->getOffset() +
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                          align_frag->getPrevNode()->size());
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // insert stub fragment
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pStub.setParent(sd);
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    sd->getFragmentList().insert(end(), &pStub);
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    pStub.setOffset(pStub.getPrevNode()->getOffset() +
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    pStub.getPrevNode()->size());
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return !exist;
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// addRelocation - add a relocation into island
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool BranchIsland::addRelocation(Relocation& pReloc)
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_Relocations.push_back(&pReloc);
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
149