• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setLocal(const ResolveInfo * pInfo)75   void setLocal(const ResolveInfo* pInfo) {
76     m_GOTTypeMap[pInfo] = false;
77   }
78 
setGlobal(const ResolveInfo * pInfo)79   void setGlobal(const ResolveInfo* pInfo) {
80     m_GOTTypeMap[pInfo] = true;
81   }
82 
isLocal(const ResolveInfo * pInfo)83   bool isLocal(const ResolveInfo* pInfo) {
84     return m_GOTTypeMap[pInfo] == false;
85   }
86 
isGlobal(const ResolveInfo * pInfo)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