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