Home | History | Annotate | Download | only in Mips
      1 //===- MipsGOT.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_MIPS_GOT_H
     10 #define MCLD_MIPS_GOT_H
     11 #include <map>
     12 #include <vector>
     13 
     14 #ifdef ENABLE_UNITTEST
     15 #include <gtest.h>
     16 #endif
     17 
     18 #include <llvm/ADT/DenseMap.h>
     19 #include <llvm/ADT/DenseSet.h>
     20 
     21 #include <mcld/ADT/SizeTraits.h>
     22 #include <mcld/Target/GOT.h>
     23 
     24 namespace mcld
     25 {
     26 class Input;
     27 class LDSection;
     28 class LDSymbol;
     29 class MemoryRegion;
     30 class OutputRelocSection;
     31 
     32 /** \class MipsGOTEntry
     33  *  \brief GOT Entry with size of 4 bytes
     34  */
     35 class MipsGOTEntry : public GOT::Entry<4>
     36 {
     37 public:
     38   MipsGOTEntry(uint64_t pContent, SectionData* pParent);
     39 };
     40 
     41 /** \class MipsGOT
     42  *  \brief Mips Global Offset Table.
     43  */
     44 class MipsGOT : public GOT
     45 {
     46 public:
     47   MipsGOT(LDSection& pSection);
     48 
     49   /// Address of _gp_disp symbol.
     50   SizeTraits<32>::Address getGPDispAddress() const;
     51 
     52   uint64_t emit(MemoryRegion& pRegion);
     53 
     54   void initializeScan(const Input& pInput);
     55   void finalizeScan(const Input& pInput);
     56 
     57   bool reserveLocalEntry(ResolveInfo& pInfo);
     58   bool reserveGlobalEntry(ResolveInfo& pInfo);
     59 
     60   size_t getLocalNum() const;   ///< number of local symbols in primary GOT
     61   size_t getGlobalNum() const;  ///< total number of global symbols
     62 
     63   bool isPrimaryGOTConsumed();
     64 
     65   MipsGOTEntry* consumeLocal();
     66   MipsGOTEntry* consumeGlobal();
     67 
     68   SizeTraits<32>::Address getGPAddr(const Input& pInput) const;
     69   SizeTraits<32>::Offset getGPRelOffset(const Input& pInput,
     70                                         const MipsGOTEntry& pEntry) const;
     71 
     72   void recordEntry(const ResolveInfo* pInfo, MipsGOTEntry* pEntry);
     73   MipsGOTEntry* lookupEntry(const ResolveInfo* pInfo);
     74 
     75   void setLocal(const ResolveInfo* pInfo) {
     76     m_GOTTypeMap[pInfo] = false;
     77   }
     78 
     79   void setGlobal(const ResolveInfo* pInfo) {
     80     m_GOTTypeMap[pInfo] = true;
     81   }
     82 
     83   bool isLocal(const ResolveInfo* pInfo) {
     84     return m_GOTTypeMap[pInfo] == false;
     85   }
     86 
     87   bool isGlobal(const ResolveInfo* pInfo) {
     88     return m_GOTTypeMap[pInfo] == true;
     89   }
     90 
     91   /// hasGOT1 - return if this got section has any GOT1 entry
     92   bool hasGOT1() const;
     93 
     94   bool hasMultipleGOT() const;
     95 
     96   /// Create GOT entries and reserve dynrel entries.
     97   void finalizeScanning(OutputRelocSection& pRelDyn);
     98 
     99   /// Compare two symbols to define order in the .dynsym.
    100   bool dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const;
    101 
    102 private:
    103   /** \class GOTMultipart
    104    *  \brief GOTMultipart counts local and global entries in the GOT.
    105    */
    106   struct GOTMultipart
    107   {
    108     GOTMultipart(size_t local = 0, size_t global = 0);
    109 
    110     typedef llvm::DenseSet<const Input*> InputSetType;
    111 
    112     size_t m_LocalNum;  ///< number of reserved local entries
    113     size_t m_GlobalNum; ///< number of reserved global entries
    114 
    115     size_t m_ConsumedLocal;       ///< consumed local entries
    116     size_t m_ConsumedGlobal;      ///< consumed global entries
    117 
    118     MipsGOTEntry* m_pLastLocal;   ///< the last consumed local entry
    119     MipsGOTEntry* m_pLastGlobal;  ///< the last consumed global entry
    120 
    121     InputSetType m_Inputs;
    122 
    123     bool isConsumed() const;
    124 
    125     void consumeLocal();
    126     void consumeGlobal();
    127   };
    128 
    129   typedef std::vector<GOTMultipart> MultipartListType;
    130 
    131   typedef llvm::DenseSet<const ResolveInfo*> SymbolSetType;
    132   typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolUniqueMapType;
    133 
    134   MultipartListType m_MultipartList;  ///< list of GOT's descriptors
    135   const Input* m_pInput;              ///< current input
    136   SymbolSetType m_MergedGlobalSymbols; ///< merged global symbols from
    137   SymbolUniqueMapType m_InputGlobalSymbols; ///< input global symbols
    138   SymbolSetType m_MergedLocalSymbols;
    139   SymbolSetType m_InputLocalSymbols;
    140 
    141   size_t m_CurrentGOTPart;
    142 
    143   typedef llvm::DenseMap<const LDSymbol*, unsigned> SymbolOrderMapType;
    144   SymbolOrderMapType m_SymbolOrderMap;
    145 
    146   void initGOTList();
    147   void changeInput();
    148   bool isGOTFull() const;
    149   void split();
    150   void reserve(size_t pNum);
    151 
    152 private:
    153   typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType;
    154 
    155   SymbolTypeMapType m_GOTTypeMap;
    156 
    157 private:
    158   struct GotEntryKey
    159   {
    160     size_t m_GOTPage;
    161     const ResolveInfo* m_pInfo;
    162 
    163     bool operator<(const GotEntryKey& key) const
    164     {
    165       if (m_GOTPage == key.m_GOTPage)
    166         return m_pInfo < key.m_pInfo;
    167       else
    168         return m_GOTPage < key.m_GOTPage;
    169     }
    170   };
    171 
    172   typedef std::map<GotEntryKey, MipsGOTEntry*> GotEntryMapType;
    173   GotEntryMapType m_GotEntriesMap;
    174 };
    175 
    176 } // namespace of mcld
    177 
    178 #endif
    179 
    180