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