MipsGOTPLT.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- MipsGOTPLT.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 <llvm/Support/Casting.h>
10#include "MipsGOTPLT.h"
11
12namespace {
13  typedef mcld::GOT::Entry<4> GOTPLTEntry;
14
15  const size_t MipsGOTPLT0Num = 2;
16}
17
18namespace mcld {
19
20//===----------------------------------------------------------------------===//
21// MipsGOTPLT
22//===----------------------------------------------------------------------===//
23MipsGOTPLT::MipsGOTPLT(LDSection& pSection)
24  : GOT(pSection)
25{
26  // Create header's entries.
27  new GOTPLTEntry(0, m_SectionData);
28  new GOTPLTEntry(0, m_SectionData);
29  m_Last = ++m_SectionData->begin();
30}
31
32void MipsGOTPLT::reserve(size_t pNum)
33{
34  for (size_t i = 0; i < pNum; i++)
35    new GOTPLTEntry(0, m_SectionData);
36}
37
38uint64_t MipsGOTPLT::emit(MemoryRegion& pRegion)
39{
40  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
41
42  uint64_t result = 0;
43  for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) {
44    GOTPLTEntry* got = &(llvm::cast<GOTPLTEntry>((*it)));
45    *buffer = static_cast<uint32_t>(got->getValue());
46    result += got->size();
47  }
48  return result;
49}
50
51Fragment* MipsGOTPLT::consume()
52{
53  ++m_Last;
54  assert(m_Last != m_SectionData->end() &&
55         "There is no reserved GOTPLT entries");
56  return &(*m_Last);
57}
58
59bool MipsGOTPLT::hasGOT1() const
60{
61  return m_SectionData->size() > MipsGOTPLT0Num;
62}
63
64uint64_t MipsGOTPLT::getEntryAddr(size_t num) const
65{
66  return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize;
67}
68
69void MipsGOTPLT::applyAllGOTPLT(uint64_t pltAddr)
70{
71  iterator it = begin();
72  llvm::cast<GOTPLTEntry>(*it++).setValue(0); // PLT lazy resolver
73  llvm::cast<GOTPLTEntry>(*it++).setValue(0); // Module pointer
74
75  for (; it != end(); ++it)
76    llvm::cast<GOTPLTEntry>(*it).setValue(pltAddr);
77}
78
79} //end mcld namespace
80