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