X86GOTPLT.cpp revision cedee4b38f4786845183be7f5916dd520a170ae0
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
10#include "X86GOTPLT.h"
11
12#include <new>
13
14#include <llvm/Support/Casting.h>
15
16#include <mcld/LD/LDFileFormat.h>
17#include <mcld/Support/MsgHandling.h>
18
19namespace {
20  const uint64_t X86GOTPLTEntrySize = 4;
21}
22
23namespace mcld {
24
25//===----------------------------------------------------------------------===//
26// X86GOTPLT
27//===----------------------------------------------------------------------===//
28X86GOTPLT::X86GOTPLT(LDSection& pSection, SectionData& pSectionData)
29  : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator()
30{
31  GOTEntry* Entry = 0;
32
33  // Create GOT0 entries.
34  for (size_t i = 0; i < X86GOTPLT0Num; i++) {
35    Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize,
36                                        &m_SectionData);
37
38    if (!Entry)
39      fatal(diag::fail_allocate_memory_got);
40
41    m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize);
42  }
43
44  // Skip GOT0 entries.
45  iterator it = m_SectionData.begin();
46
47  for (size_t i = 1; i < X86GOTPLT0Num; ++i) {
48    assert((it != m_SectionData.end()) &&
49           "Generation of GOT0 entries is incomplete!");
50
51    ++it;
52  }
53
54  m_GOTPLTIterator = it;
55}
56
57X86GOTPLT::~X86GOTPLT()
58{
59}
60
61X86GOTPLT::iterator X86GOTPLT::begin()
62{
63  return m_SectionData.begin();
64}
65
66X86GOTPLT::const_iterator X86GOTPLT::begin() const
67{
68  return m_SectionData.begin();
69}
70
71X86GOTPLT::iterator X86GOTPLT::end()
72{
73  return m_SectionData.end();
74}
75
76X86GOTPLT::const_iterator X86GOTPLT::end() const
77{
78  return m_SectionData.end();
79}
80
81void X86GOTPLT::applyGOT0(uint64_t pAddress)
82{
83  llvm::cast<GOTEntry>
84    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
85}
86
87void X86GOTPLT::reserveEntry(size_t pNum)
88{
89  GOTEntry* got_entry = NULL;
90  for (size_t i = 0; i < pNum; ++i) {
91    got_entry = new GOTEntry(0, getEntrySize(),&(getSectionData()));
92    if (!got_entry)
93      fatal(diag::fail_allocate_memory_got);
94
95    m_Section.setSize(m_Section.size() + getEntrySize());
96  }
97}
98
99void X86GOTPLT::applyAllGOTPLT(uint64_t pPLTBase,
100                               unsigned int pPLT0Size,
101                               unsigned int pPLT1Size)
102{
103  iterator it = begin();
104  // skip GOT0
105  for (size_t i = 0; i < X86GOTPLT0Num; ++i)
106    ++it;
107  // address of corresponding plt entry
108  uint64_t plt_addr = pPLTBase + pPLT0Size;
109  for (; it != end() ; ++it) {
110    llvm::cast<GOTEntry>(*it).setContent(plt_addr + 6);
111    plt_addr += pPLT1Size;
112  }
113}
114
115GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
116{
117  return m_GOTPLTMap[&pSymbol];
118}
119
120GOTEntry* X86GOTPLT::getEntry(const ResolveInfo& pInfo, bool& pExist)
121{
122  GOTEntry *&Entry = m_GOTPLTMap[&pInfo];
123  pExist = 1;
124
125  if (!Entry) {
126    pExist = 0;
127
128    ++m_GOTPLTIterator;
129    assert(m_GOTPLTIterator != m_SectionData.getFragmentList().end()
130           && "The number of GOT Entries and ResolveInfo doesn't match!");
131
132    Entry = llvm::cast<GOTEntry>(&(*m_GOTPLTIterator));
133  }
134
135  return Entry;
136}
137
138} //end mcld namespace
139