• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 namespace {
13   typedef mcld::GOT::Entry<4> GOTPLTEntry;
14 
15   const size_t MipsGOTPLT0Num = 2;
16 }
17 
18 namespace mcld {
19 
20 //===----------------------------------------------------------------------===//
21 // MipsGOTPLT
22 //===----------------------------------------------------------------------===//
MipsGOTPLT(LDSection & pSection)23 MipsGOTPLT::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 
reserve(size_t pNum)32 void MipsGOTPLT::reserve(size_t pNum)
33 {
34   for (size_t i = 0; i < pNum; i++)
35     new GOTPLTEntry(0, m_SectionData);
36 }
37 
emit(MemoryRegion & pRegion)38 uint64_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 
consume()51 Fragment* 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 
hasGOT1() const59 bool MipsGOTPLT::hasGOT1() const
60 {
61   return m_SectionData->size() > MipsGOTPLT0Num;
62 }
63 
getEntryAddr(size_t num) const64 uint64_t MipsGOTPLT::getEntryAddr(size_t num) const
65 {
66   return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize;
67 }
68 
applyAllGOTPLT(uint64_t pltAddr)69 void 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