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)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 reserve(size_t pNum)32void 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)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 consume()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 hasGOT1() const59bool MipsGOTPLT::hasGOT1() const 60 { 61 return m_SectionData->size() > MipsGOTPLT0Num; 62 } 63 getEntryAddr(size_t num) const64uint64_t MipsGOTPLT::getEntryAddr(size_t num) const 65 { 66 return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; 67 } 68 applyAllGOTPLT(uint64_t pltAddr)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