15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsGOT.h ----------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_MIPS_GOT_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_MIPS_GOT_H
11f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <map>
12f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <vector>
13f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/ADT/DenseMap.h>
19f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <llvm/ADT/DenseSet.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/ADT/SizeTraits.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GOT.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass Input;
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass LDSection;
28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass LDSymbol;
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MemoryRegion;
30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesclass OutputRelocSection;
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
32d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/** \class MipsGOTEntry
33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao *  \brief GOT Entry with size of 4 bytes
34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao */
35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass MipsGOTEntry : public GOT::Entry<4>
36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaopublic:
38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  MipsGOTEntry(uint64_t pContent, SectionData* pParent);
39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao};
40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class MipsGOT
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief Mips Global Offset Table.
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MipsGOT : public GOT
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MipsGOT(LDSection& pSection);
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// Address of _gp_disp symbol.
50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SizeTraits<32>::Address getGPDispAddress() const;
51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t emit(MemoryRegion& pRegion);
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void initializeScan(const Input& pInput);
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void finalizeScan(const Input& pInput);
56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
57f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool reserveLocalEntry(ResolveInfo& pInfo);
58f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool reserveGlobalEntry(ResolveInfo& pInfo);
59f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t getLocalNum() const;   ///< number of local symbols in primary GOT
61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t getGlobalNum() const;  ///< total number of global symbols
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool isPrimaryGOTConsumed();
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  MipsGOTEntry* consumeLocal();
66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  MipsGOTEntry* consumeGlobal();
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
68f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SizeTraits<32>::Address getGPAddr(const Input& pInput) const;
69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SizeTraits<32>::Offset getGPRelOffset(const Input& pInput,
70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                        const MipsGOTEntry& pEntry) const;
71f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
72f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void recordEntry(const ResolveInfo* pInfo, MipsGOTEntry* pEntry);
73f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  MipsGOTEntry* lookupEntry(const ResolveInfo* pInfo);
74f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  void setLocal(const ResolveInfo* pInfo) {
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_GOTTypeMap[pInfo] = false;
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  void setGlobal(const ResolveInfo* pInfo) {
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_GOTTypeMap[pInfo] = true;
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool isLocal(const ResolveInfo* pInfo) {
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return m_GOTTypeMap[pInfo] == false;
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool isGlobal(const ResolveInfo* pInfo) {
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return m_GOTTypeMap[pInfo] == true;
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// hasGOT1 - return if this got section has any GOT1 entry
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool hasGOT1() const;
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasMultipleGOT() const;
95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// Create GOT entries and reserve dynrel entries.
97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void finalizeScanning(OutputRelocSection& pRelDyn);
98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// Compare two symbols to define order in the .dynsym.
100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool dynSymOrderCompare(const LDSymbol* pX, const LDSymbol* pY) const;
101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoprivate:
103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /** \class GOTMultipart
104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   *  \brief GOTMultipart counts local and global entries in the GOT.
105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines   */
106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  struct GOTMultipart
107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  {
108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    GOTMultipart(size_t local = 0, size_t global = 0);
109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    typedef llvm::DenseSet<const Input*> InputSetType;
111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    size_t m_LocalNum;  ///< number of reserved local entries
113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    size_t m_GlobalNum; ///< number of reserved global entries
114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    size_t m_ConsumedLocal;       ///< consumed local entries
116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    size_t m_ConsumedGlobal;      ///< consumed global entries
117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    MipsGOTEntry* m_pLastLocal;   ///< the last consumed local entry
119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    MipsGOTEntry* m_pLastGlobal;  ///< the last consumed global entry
120f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
121f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    InputSetType m_Inputs;
122f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
123f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    bool isConsumed() const;
124f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
125f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    void consumeLocal();
126f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    void consumeGlobal();
127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  };
128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef std::vector<GOTMultipart> MultipartListType;
130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef llvm::DenseSet<const ResolveInfo*> SymbolSetType;
132f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolUniqueMapType;
133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  MultipartListType m_MultipartList;  ///< list of GOT's descriptors
135f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  const Input* m_pInput;              ///< current input
136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolSetType m_MergedGlobalSymbols; ///< merged global symbols from
137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolUniqueMapType m_InputGlobalSymbols; ///< input global symbols
138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolSetType m_MergedLocalSymbols;
139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolSetType m_InputLocalSymbols;
140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t m_CurrentGOTPart;
142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef llvm::DenseMap<const LDSymbol*, unsigned> SymbolOrderMapType;
144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolOrderMapType m_SymbolOrderMap;
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void initGOTList();
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void changeInput();
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool isGOTFull() const;
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void split();
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void reserve(size_t pNum);
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef llvm::DenseMap<const ResolveInfo*, bool> SymbolTypeMapType;
154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  SymbolTypeMapType m_GOTTypeMap;
156d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesprivate:
158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  struct GotEntryKey
159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  {
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    size_t m_GOTPage;
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    const ResolveInfo* m_pInfo;
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    bool operator<(const GotEntryKey& key) const
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    {
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      if (m_GOTPage == key.m_GOTPage)
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return m_pInfo < key.m_pInfo;
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      else
168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        return m_GOTPage < key.m_GOTPage;
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    }
170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  };
171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  typedef std::map<GotEntryKey, MipsGOTEntry*> GotEntryMapType;
173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  GotEntryMapType m_GotEntriesMap;
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
180