X86GOT.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
1//===- impl.cpp -----------------------------------------------------------===//
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#include "X86GOT.h"
10#include <mcld/LD/LDFileFormat.h>
11#include <llvm/Support/ErrorHandling.h>
12#include <new>
13
14namespace {
15  const size_t X86GOTEntrySize = 4;
16}
17
18using namespace mcld;
19
20//===----------------------------------------------------------------------===//
21// X86GOT
22X86GOT::X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
23             : GOT(pSection, pSectionData, X86GOTEntrySize),
24               m_GeneralGOTNum(0), m_GOTPLTNum(0), m_GeneralGOTIterator(),
25               m_GOTPLTIterator(), m_LastGOT0()
26{
27  GOTEntry* Entry = 0;
28
29  // Create GOT0 entries.
30  for (unsigned int i = 0; i < X86GOT0Num; i++) {
31    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
32                                        &m_SectionData);
33
34    if (!Entry)
35      llvm::report_fatal_error("Allocating GOT0 entries failed!");
36
37    m_Section.setSize(m_Section.size() + X86GOTEntrySize);
38  }
39
40  // Skip GOT0 entries.
41  iterator it = m_SectionData.begin();
42  iterator ie = m_SectionData.end();
43
44  for (unsigned int i = 1; i < X86GOT0Num; ++i) {
45    if (it == ie)
46      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
47
48    ++it;
49  }
50
51  m_LastGOT0 = it;
52  m_GeneralGOTIterator = it;
53  m_GOTPLTIterator = it;
54}
55
56X86GOT::~X86GOT()
57{
58}
59
60void X86GOT::reserveEntry(size_t pNum)
61{
62  GOTEntry* Entry = 0;
63
64  for (size_t i = 0; i < pNum; i++) {
65    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
66                                        &m_SectionData);
67
68    if (!Entry)
69      llvm::report_fatal_error("Allocating new memory for GOTEntry failed");
70
71    m_Section.setSize(m_Section.size() + X86GOTEntrySize);
72    ++m_GeneralGOTNum;
73  }
74}
75
76
77GOTEntry* X86GOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
78{
79  GOTEntry *&Entry = m_GeneralGOTMap[&pInfo];
80  pExist = 1;
81
82  if (!Entry) {
83    pExist = 0;
84
85    ++m_GeneralGOTIterator;
86    assert(m_GeneralGOTIterator != m_SectionData.getFragmentList().end()
87           && "The number of GOT Entries and ResolveInfo doesn't match!");
88
89    Entry = llvm::cast<GOTEntry>(&(*m_GeneralGOTIterator));
90  }
91
92  return Entry;
93}
94
95void X86GOT::applyGOT0(uint64_t pAddress)
96{
97  llvm::cast<GOTEntry>
98    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
99}
100
101X86GOT::iterator X86GOT::begin()
102{
103  return m_SectionData.getFragmentList().begin();
104}
105
106X86GOT::const_iterator X86GOT::begin() const
107{
108  return m_SectionData.getFragmentList().begin();
109}
110
111X86GOT::iterator X86GOT::end()
112{
113  return m_SectionData.getFragmentList().end();
114}
115
116X86GOT::const_iterator X86GOT::end() const
117{
118  return m_SectionData.getFragmentList().end();
119}
120
121unsigned int X86GOT::getGOTPLTNum() const
122{ return m_GOTPLTNum; }
123
124X86GOT::iterator X86GOT::getLastGOT0()
125{ return m_LastGOT0; }
126
127const X86GOT::iterator X86GOT::getLastGOT0() const
128{ return m_LastGOT0; }
129
130