MipsGOTPLT.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
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 12namespace { 13 typedef mcld::GOT::Entry<4> GOTPLTEntry; 14 15 const size_t MipsGOTPLT0Num = 2; 16} 17 18namespace mcld { 19 20//===----------------------------------------------------------------------===// 21// MipsGOTPLT 22//===----------------------------------------------------------------------===// 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 32void MipsGOTPLT::reserve(size_t pNum) 33{ 34 for (size_t i = 0; i < pNum; i++) 35 new GOTPLTEntry(0, m_SectionData); 36} 37 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 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 59bool MipsGOTPLT::hasGOT1() const 60{ 61 return m_SectionData->size() > MipsGOTPLT0Num; 62} 63 64uint64_t MipsGOTPLT::getEntryAddr(size_t num) const 65{ 66 return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; 67} 68 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