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