1//===- BranchIsland.h -----------------------------------------------------===// 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//===----------------------------------------------------------------------===// 9#ifndef MCLD_LD_BRANCH_ISLAND_H 10#define MCLD_LD_BRANCH_ISLAND_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14 15#include <llvm/Support/DataTypes.h> 16#include <llvm/ADT/StringRef.h> 17#include <mcld/ADT/HashEntry.h> 18#include <mcld/ADT/HashTable.h> 19#include <mcld/ADT/StringHash.h> 20#include <mcld/LD/SectionData.h> 21#include <mcld/LD/LDSymbol.h> 22#include <mcld/Fragment/Stub.h> 23#include <string> 24 25namespace mcld { 26 27class Stub; 28class Relocation; 29 30/** \class BranchIsland 31 * \brief BranchIsland is a collection of stubs 32 * 33 */ 34class BranchIsland 35{ 36public: 37 typedef SectionData::iterator iterator; 38 typedef SectionData::const_iterator const_iterator; 39 40 typedef std::vector<Relocation*> RelocationListType; 41 typedef RelocationListType::iterator reloc_iterator; 42 typedef RelocationListType::const_iterator const_reloc_iterator; 43 44public: 45 /* 46 * ---------- 47 * --- Entry -> | Island | -> Exit --- 48 * ---------- 49 */ 50 51 /// BranchIsland - constructor 52 /// @param pEntryFrag - the entry fragment to the island 53 /// @param pMaxSize - the max size the island can be 54 /// @param pIndex - the inedx in the island factory 55 BranchIsland(Fragment& pEntryFrag, size_t pMaxSize, size_t pIndex); 56 57 ~BranchIsland(); 58 59 /// fragment iterators of the island 60 iterator begin(); 61 62 const_iterator begin() const; 63 64 iterator end(); 65 66 const_iterator end() const; 67 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::ELF> 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