BranchIsland.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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#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::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