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