BranchIsland.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen//===- BranchIsland.h -----------------------------------------------------===// 2a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// 3a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// The MCLinker Project 4a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// 5a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// This file is distributed under the University of Illinois Open Source 6a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// License. See LICENSE.TXT for details. 7a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen// 8a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen//===----------------------------------------------------------------------===// 9a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#ifndef MCLD_LD_BRANCHISLAND_H 10a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#define MCLD_LD_BRANCHISLAND_H 11a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#ifdef ENABLE_UNITTEST 12a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <gtest.h> 13a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#endif 14a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 15a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <llvm/Support/DataTypes.h> 16a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <llvm/ADT/StringRef.h> 17a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <mcld/ADT/HashEntry.h> 18a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <mcld/ADT/HashTable.h> 19a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <mcld/ADT/StringHash.h> 20a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <mcld/LD/SectionData.h> 217e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <mcld/LD/LDSymbol.h> 22a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen#include <mcld/Fragment/Stub.h> 23cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen#include <string> 24a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 25a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissennamespace mcld { 26a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 27a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenclass Stub; 28a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenclass Relocation; 29a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 30a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen/** \class BranchIsland 318b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen * \brief BranchIsland is a collection of stubs 32a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 33b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen */ 34b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenclass BranchIsland 35b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen{ 36b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenpublic: 37a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen typedef SectionData::iterator iterator; 38a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen typedef SectionData::const_iterator const_iterator; 39a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 40a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen typedef std::vector<Relocation*> RelocationListType; 41a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen typedef RelocationListType::iterator reloc_iterator; 42cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen typedef RelocationListType::const_iterator const_reloc_iterator; 437e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 44a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenpublic: 45a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen /* 46a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * ---------- 478b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen * --- Entry -> | Island | -> Exit --- 488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen * ---------- 498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen */ 50a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 51a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen /// BranchIsland - constructor 52a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen /// @param pEntryFrag - the entry fragment to the island 537e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim /// @param pMaxSize - the max size the island can be 547e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim /// @param pIndex - the inedx in the island factory 55a6cdabf38b29ee98bdb3e874b4e2978dbc409624Marco Nelissen BranchIsland(Fragment& pEntryFrag, size_t pMaxSize, size_t pIndex); 56a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 57a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ~BranchIsland(); 58a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 59a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen /// fragment iterators of the island 60a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen iterator begin(); 61a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 62a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen const_iterator begin() const; 63a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 64a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen iterator end(); 65a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 66a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen const_iterator end() const; 67a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 68 /// relocation iterators of the island 69 reloc_iterator reloc_begin() 70 { return m_Relocations.begin(); } 71 72 const_reloc_iterator reloc_begin() const 73 { return m_Relocations.begin(); } 74 75 reloc_iterator reloc_end() 76 { return m_Relocations.end(); } 77 78 const_reloc_iterator reloc_end() const 79 { return m_Relocations.end(); } 80 81 /// observers 82 uint64_t offset() const; 83 84 size_t size() const; 85 86 size_t maxSize() const; 87 88 const std::string& name() const; 89 90 size_t numOfStubs() const; 91 92 /// findStub - return true if there is a stub built from the given prototype 93 /// for the given relocation 94 Stub* findStub(const Stub* pPrototype, const Relocation& pReloc); 95 96 /// addStub - add a stub into the island 97 bool addStub(const Stub* pPrototype, const Relocation& pReloc, Stub& pStub); 98 99 /// addRelocation - add a relocation into island 100 bool addRelocation(Relocation& pReloc); 101 102private: 103 /** \class Key 104 * \brief Key to recognize a stub in the island. 105 * 106 */ 107 class Key 108 { 109 public: 110 Key(const Stub* pPrototype, const LDSymbol* pSymbol, Stub::SWord pAddend) 111 : m_pPrototype(pPrototype), m_pSymbol(pSymbol), m_Addend(pAddend) 112 { } 113 114 ~Key() 115 { } 116 117 const Stub* prototype() const { return m_pPrototype; } 118 119 const LDSymbol* symbol() const { return m_pSymbol; } 120 121 Stub::SWord addend() const { return m_Addend; } 122 123 struct Hash 124 { 125 size_t operator() (const Key& KEY) const 126 { 127 llvm::StringRef sym_name(KEY.symbol()->name()); 128 hash::StringHash<hash::DJB> str_hasher; 129 return (size_t((uintptr_t)KEY.prototype())) ^ 130 str_hasher(sym_name) ^ 131 KEY.addend(); 132 } 133 }; 134 135 struct Compare 136 { 137 bool operator() (const Key& KEY1, const Key& KEY2) const 138 { 139 return (KEY1.prototype() == KEY2.prototype()) && 140 (KEY1.symbol() == KEY2.symbol()) && 141 (KEY1.addend() == KEY2.addend()); 142 } 143 }; 144 145 private: 146 const Stub* m_pPrototype; 147 const LDSymbol* m_pSymbol; 148 Stub::SWord m_Addend; 149 }; 150 151 typedef HashEntry<Key, Stub*, Key::Compare> StubEntryType; 152 153 typedef HashTable<StubEntryType, 154 Key::Hash, 155 EntryFactory<StubEntryType> > StubMapType; 156private: 157 Fragment& m_Entry; // entry fragment of the island 158 Fragment* m_pExit; // exit fragment of the island 159 Fragment* m_pRear; // rear fragment of the island 160 size_t m_MaxSize; 161 std::string m_Name; 162 StubMapType m_StubMap; 163 /// m_Relocations - list of relocations created for stubs in this island 164 RelocationListType m_Relocations; 165}; 166 167} // namespace of mcld 168 169#endif 170 171