X86GOTPLT.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
1//===- X86GOTPLT.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 "X86GOTPLT.h"
10#include "mcld/LD/LDFileFormat.h"
11#include <llvm/Support/ErrorHandling.h>
12#include <new>
13
14namespace {
15  const uint64_t X86GOTPLTEntrySize = 4;
16}
17
18namespace mcld {
19
20//===----------------------------------------------------------------------===//
21// X86GOTPLT
22X86GOTPLT::X86GOTPLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
23  : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator()
24{
25  GOTEntry* Entry = 0;
26
27  // Create GOT0 entries.
28  for (int i = 0; i < 3; i++) {
29    Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize,
30                                        &m_SectionData);
31
32    if (!Entry)
33      llvm::report_fatal_error("Allocating GOT0 entries failed!");
34
35    m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize);
36  }
37
38  // Skip GOT0 entries.
39  iterator it = m_SectionData.begin();
40  iterator ie = m_SectionData.end();
41
42  for (size_t i = 1; i < X86GOT0Num; ++i) {
43    if (it == ie)
44      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
45
46    ++it;
47  }
48
49  m_GOTPLTIterator = it;
50}
51
52X86GOTPLT::~X86GOTPLT()
53{
54}
55
56X86GOTPLT::iterator X86GOTPLT::begin()
57{
58  return m_SectionData.begin();
59}
60
61X86GOTPLT::const_iterator X86GOTPLT::begin() const
62{
63  return m_SectionData.begin();
64}
65
66X86GOTPLT::iterator X86GOTPLT::end()
67{
68  return m_SectionData.end();
69}
70
71X86GOTPLT::const_iterator X86GOTPLT::end() const
72{
73  return m_SectionData.end();
74}
75
76void X86GOTPLT::applyGOT0(const uint64_t pAddress)
77{
78  llvm::cast<GOTEntry>
79    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
80}
81
82void X86GOTPLT::reserveGOTPLTEntry()
83{
84    GOTEntry* got_entry = 0;
85
86    got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData()));
87
88    if (!got_entry)
89      llvm::report_fatal_error("Allocating new memory for GOT failed!");
90
91    m_Section.setSize(m_Section.size() + getEntrySize());
92}
93
94void X86GOTPLT::applyAllGOTPLT(const uint64_t pPLTBase)
95{
96  iterator gotplt_it = begin();
97  iterator gotplt_ie = end();
98
99  for (; gotplt_it != gotplt_ie; ++gotplt_it)
100    llvm::cast<GOTEntry>(*gotplt_it).setContent(pPLTBase);
101}
102
103GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
104{
105  return m_GOTPLTMap[&pSymbol];
106}
107
108X86GOTPLT::iterator X86GOTPLT::getNextGOTPLTEntry()
109{
110  return ++m_GOTPLTIterator;
111}
112
113} //end mcld namespace
114