MipsGOT.h revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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
24namespace mcld
25{
26class Input;
27class LDSection;
28class LDSymbol;
29class MemoryRegion;
30class OutputRelocSection;
31
32/** \class MipsGOTEntry
33 *  \brief GOT Entry with size of 4 bytes
34 */
35class MipsGOTEntry : public GOT::Entry<4>
36{
37public:
38  MipsGOTEntry(uint64_t pContent, SectionData* pParent);
39};
40
41/** \class MipsGOT
42 *  \brief Mips Global Offset Table.
43 */
44class MipsGOT : public GOT
45{
46public:
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
102private:
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
152private:
153  typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType;
154
155  SymbolTypeMapType m_GOTTypeMap;
156
157private:
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