blob: e3237df01964c0e82ba9bbcec2cf0cc7ddbdf563 [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- BranchIsland.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//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -08009#include "mcld/LD/BranchIsland.h"
10
11#include "mcld/Fragment/AlignFragment.h"
12#include "mcld/Fragment/Stub.h"
13#include "mcld/LD/LDSection.h"
14#include "mcld/LD/ResolveInfo.h"
Shih-wei Liao22add6f2012-12-15 17:21:00 -080015
16#include <sstream>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070017
Stephen Hines37b74a32014-11-26 18:48:20 -080018namespace mcld {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070019
Stephen Hinescfcb2242016-03-08 00:18:09 -080020//============================================================================//
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070021// BranchIsland
Stephen Hinescfcb2242016-03-08 00:18:09 -080022//============================================================================//
Stephen Hines37b74a32014-11-26 18:48:20 -080023BranchIsland::BranchIsland(Fragment& pEntryFrag, size_t pMaxSize, size_t pIndex)
24 : m_Entry(pEntryFrag),
25 m_pExit(pEntryFrag.getNextNode()),
26 m_pRear(NULL),
27 m_MaxSize(pMaxSize),
28 m_Name("island-") {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080029 // island name
30 std::ostringstream index;
31 index << pIndex;
32 m_Name.append(index.str());
33}
34
Stephen Hines37b74a32014-11-26 18:48:20 -080035BranchIsland::~BranchIsland() {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080036}
37
38/// fragment iterators of the island
Stephen Hines37b74a32014-11-26 18:48:20 -080039SectionData::iterator BranchIsland::begin() {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080040 return ++iterator(&m_Entry);
41}
42
Stephen Hines37b74a32014-11-26 18:48:20 -080043SectionData::const_iterator BranchIsland::begin() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080044 return ++iterator(&m_Entry);
45}
46
Stephen Hines37b74a32014-11-26 18:48:20 -080047SectionData::iterator BranchIsland::end() {
48 if (m_pExit != NULL)
Shih-wei Liao22add6f2012-12-15 17:21:00 -080049 return iterator(m_pExit);
50 return m_Entry.getParent()->end();
51}
52
Stephen Hines37b74a32014-11-26 18:48:20 -080053SectionData::const_iterator BranchIsland::end() const {
54 if (m_pExit != NULL)
Shih-wei Liao22add6f2012-12-15 17:21:00 -080055 return iterator(m_pExit);
56 return m_Entry.getParent()->end();
57}
58
Stephen Hines37b74a32014-11-26 18:48:20 -080059uint64_t BranchIsland::offset() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080060 return m_Entry.getOffset() + m_Entry.size();
61}
62
Stephen Hines37b74a32014-11-26 18:48:20 -080063size_t BranchIsland::size() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080064 size_t size = 0x0;
Stephen Hines37b74a32014-11-26 18:48:20 -080065 if (numOfStubs() != 0x0) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080066 size = m_pRear->getOffset() + m_pRear->size() -
67 m_Entry.getNextNode()->getOffset();
68 }
69 return size;
70}
71
Stephen Hines37b74a32014-11-26 18:48:20 -080072size_t BranchIsland::maxSize() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080073 return m_MaxSize;
74}
75
Stephen Hines37b74a32014-11-26 18:48:20 -080076const std::string& BranchIsland::name() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080077 return m_Name;
78}
79
Stephen Hines37b74a32014-11-26 18:48:20 -080080size_t BranchIsland::numOfStubs() const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080081 return m_StubMap.numOfEntries();
82}
83
84/// findStub - return true if there is a stub built from the given prototype
85/// for the given relocation
Stephen Hines37b74a32014-11-26 18:48:20 -080086Stub* BranchIsland::findStub(const Stub* pPrototype, const Relocation& pReloc) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -080087 Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
88 StubMapType::iterator it = m_StubMap.find(key);
89 if (it != m_StubMap.end()) {
Stephen Hines37b74a32014-11-26 18:48:20 -080090 assert(it.getEntry()->value() != NULL);
Shih-wei Liao22add6f2012-12-15 17:21:00 -080091 return it.getEntry()->value();
92 }
93 return NULL;
94}
95
96/// addStub - add a stub into the island
97bool BranchIsland::addStub(const Stub* pPrototype,
98 const Relocation& pReloc,
Stephen Hines37b74a32014-11-26 18:48:20 -080099 Stub& pStub) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800100 bool exist = false;
101 Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
102 StubEntryType* entry = m_StubMap.insert(key, exist);
103 if (!exist) {
104 entry->setValue(&pStub);
105 m_pRear = &pStub;
106 SectionData* sd = m_Entry.getParent();
107
108 // insert alignment fragment
109 // TODO: check if we can reduce this alignment fragment for some cases
Stephen Hines37b74a32014-11-26 18:48:20 -0800110 AlignFragment* align_frag =
111 new AlignFragment(pStub.alignment(), 0x0, 1u, pStub.alignment() - 1);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800112 align_frag->setParent(sd);
113 sd->getFragmentList().insert(end(), align_frag);
114 align_frag->setOffset(align_frag->getPrevNode()->getOffset() +
115 align_frag->getPrevNode()->size());
116
117 // insert stub fragment
118 pStub.setParent(sd);
119 sd->getFragmentList().insert(end(), &pStub);
120 pStub.setOffset(pStub.getPrevNode()->getOffset() +
121 pStub.getPrevNode()->size());
122 }
123 return !exist;
124}
125
Stephen Hinescfcb2242016-03-08 00:18:09 -0800126void BranchIsland::addStub(Stub& pStub) {
127 bool exist = false;
128 Key key(&pStub, pStub.symInfo()->outSymbol(), 0);
129 m_StubMap.insert(key, exist);
130
131 m_pRear = &pStub;
132 SectionData* sd = m_Entry.getParent();
133
134 // insert alignment fragment
135 // TODO: check if we can reduce this alignment fragment for some cases
136 AlignFragment* align_frag =
137 new AlignFragment(pStub.alignment(), 0x0, 1u, pStub.alignment() - 1);
138 align_frag->setParent(sd);
139 sd->getFragmentList().insert(end(), align_frag);
140 align_frag->setOffset(align_frag->getPrevNode()->getOffset() +
141 align_frag->getPrevNode()->size());
142
143 // insert stub fragment
144 pStub.setParent(sd);
145 sd->getFragmentList().insert(end(), &pStub);
146 pStub.setOffset(pStub.getPrevNode()->getOffset() +
147 pStub.getPrevNode()->size());
148}
149
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800150/// addRelocation - add a relocation into island
Stephen Hines37b74a32014-11-26 18:48:20 -0800151bool BranchIsland::addRelocation(Relocation& pReloc) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800152 m_Relocations.push_back(&pReloc);
153 return true;
154}
155
Stephen Hines37b74a32014-11-26 18:48:20 -0800156} // namespace mcld