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