1//===- GOT.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_GLOBAL_OFFSET_TABLE_H
10#define MCLD_GLOBAL_OFFSET_TABLE_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <mcld/LD/LDSection.h>
16#include <mcld/LD/TargetFragment.h>
17
18namespace mcld
19{
20
21class GOT;
22class ResolveInfo;
23class SectionData;
24
25/** \class GOTEntry
26 *  \brief The entry of Global Offset Table
27 */
28class GOTEntry : public TargetFragment
29{
30public:
31  explicit GOTEntry(uint64_t pContent, size_t pEntrySize,
32                    SectionData* pParent);
33
34  virtual ~GOTEntry();
35
36  uint64_t& getContent()
37  { return f_Content; }
38
39  uint64_t getContent() const
40  { return f_Content; }
41
42  void setContent(uint64_t pValue)
43  { f_Content = pValue; }
44
45  static bool classof(const Fragment *pFrag)
46  { return pFrag->getKind() == Fragment::Target; }
47
48  static bool classof(const GOTEntry* pFrag)
49  { return true; }
50
51  // Override pure virtual function
52  size_t getSize() const
53  { return m_EntrySize; }
54
55protected:
56  uint64_t f_Content;
57  size_t m_EntrySize;
58};
59
60/** \class GOT
61 *  \brief The Global Offset Table
62 */
63class GOT
64{
65protected:
66  GOT(LDSection& pSection, SectionData& pSectionData, size_t pEntrySize);
67
68public:
69  virtual ~GOT();
70
71  /// entrySize - the number of bytes per entry
72  size_t getEntrySize() const;
73
74  const LDSection& getSection() const
75  { return m_Section; }
76
77  SectionData& getSectionData()
78  { return m_SectionData; }
79
80  const SectionData& getSectionData() const
81  { return m_SectionData; }
82
83public:
84  /// reserveEntry - reseve number of pNum of empty entries
85  /// Before layout, we scan all relocations to determine if GOT entries are
86  /// needed. If an entry is needed, the empty entry is reserved for layout
87  /// to adjust the fragment offset. After that, we fill up the entries when
88  /// applying relocations.
89  virtual void reserveEntry(size_t pNum = 1) = 0;
90
91  /// getEntry - get an empty entry or an exitsted filled entry with pSymbol.
92  /// @param pSymbol - the target symbol
93  /// @param pExist - ture if a filled entry with pSymbol existed, otherwise false.
94  virtual GOTEntry* getEntry(const ResolveInfo& pSymbol, bool& pExist) = 0;
95
96protected:
97  LDSection& m_Section;
98  SectionData& m_SectionData;
99  size_t f_EntrySize;
100};
101
102} // namespace of mcld
103
104#endif
105
106