X86GOTPLT.cpp revision affc150dc44fab1911775a49636d0ce85333b634
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 <mcld/Support/MsgHandling.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 (size_t i = 0; i < X86GOTPLT0Num; i++) {
29    Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize,
30                                        &m_SectionData);
31
32    if (!Entry)
33      fatal(diag::fail_allocate_memory) << "GOT0";
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 < X86GOTPLT0Num; ++i) {
43    assert((it != ie) && "Generation of GOT0 entries is incomplete!");
44
45    ++it;
46  }
47
48  m_GOTPLTIterator = it;
49}
50
51X86GOTPLT::~X86GOTPLT()
52{
53}
54
55X86GOTPLT::iterator X86GOTPLT::begin()
56{
57  return m_SectionData.begin();
58}
59
60X86GOTPLT::const_iterator X86GOTPLT::begin() const
61{
62  return m_SectionData.begin();
63}
64
65X86GOTPLT::iterator X86GOTPLT::end()
66{
67  return m_SectionData.end();
68}
69
70X86GOTPLT::const_iterator X86GOTPLT::end() const
71{
72  return m_SectionData.end();
73}
74
75void X86GOTPLT::applyGOT0(uint64_t pAddress)
76{
77  llvm::cast<GOTEntry>
78    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
79}
80
81void X86GOTPLT::reserveEntry(size_t pNum)
82{
83  GOTEntry* got_entry = NULL;
84  for (size_t i = 0; i < pNum; ++i) {
85    got_entry = new GOTEntry(0, getEntrySize(),&(getSectionData()));
86    if (!got_entry)
87      fatal(diag::fail_allocate_memory) << "GOT";
88
89    m_Section.setSize(m_Section.size() + getEntrySize());
90  }
91}
92
93void X86GOTPLT::applyAllGOTPLT(uint64_t pPLTBase,
94                               unsigned int pPLT0Size,
95                               unsigned int pPLT1Size)
96{
97  iterator it = begin();
98  // skip GOT0
99  for (size_t i = 0; i < X86GOTPLT0Num; ++i)
100    ++it;
101  // address of corresponding plt entry
102  uint64_t plt_addr = pPLTBase + pPLT0Size;
103  for (; it != end() ; ++it) {
104    llvm::cast<GOTEntry>(*it).setContent(plt_addr + 6);
105    plt_addr += pPLT1Size;
106  }
107}
108
109GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
110{
111  return m_GOTPLTMap[&pSymbol];
112}
113
114GOTEntry* X86GOTPLT::getEntry(const ResolveInfo& pInfo, bool& pExist)
115{
116  GOTEntry *&Entry = m_GOTPLTMap[&pInfo];
117  pExist = 1;
118
119  if (!Entry) {
120    pExist = 0;
121
122    ++m_GOTPLTIterator;
123    assert(m_GOTPLTIterator != m_SectionData.getFragmentList().end()
124           && "The number of GOT Entries and ResolveInfo doesn't match!");
125
126    Entry = llvm::cast<GOTEntry>(&(*m_GOTPLTIterator));
127  }
128
129  return Entry;
130}
131
132} //end mcld namespace
133