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 
13 namespace {
14 typedef mcld::GOT::Entry<4> GOTPLTEntry;
15 
16 const size_t MipsGOTPLT0Num = 2;
17 }
18 
19 namespace mcld {
20 
21 //===----------------------------------------------------------------------===//
22 // MipsGOTPLT
23 //===----------------------------------------------------------------------===//
MipsGOTPLT(LDSection & pSection)24 MipsGOTPLT::MipsGOTPLT(LDSection& pSection) : GOT(pSection) {
25   // Create header's entries.
26   new GOTPLTEntry(0, m_SectionData);
27   new GOTPLTEntry(0, m_SectionData);
28 }
29 
emit(MemoryRegion & pRegion)30 uint64_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 
create()42 Fragment* MipsGOTPLT::create() {
43   return new GOTPLTEntry(0, m_SectionData);
44 }
45 
hasGOT1() const46 bool MipsGOTPLT::hasGOT1() const {
47   return m_SectionData->size() > MipsGOTPLT0Num;
48 }
49 
getEntryAddr(size_t num) const50 uint64_t MipsGOTPLT::getEntryAddr(size_t num) const {
51   return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize;
52 }
53 
applyAllGOTPLT(uint64_t pltAddr)54 void 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