MipsGOTPLT.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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 m_Last = ++m_SectionData->begin(); 29} 30 31void MipsGOTPLT::reserve(size_t pNum) { 32 for (size_t i = 0; i < pNum; ++i) 33 new GOTPLTEntry(0, m_SectionData); 34} 35 36uint64_t MipsGOTPLT::emit(MemoryRegion& pRegion) { 37 uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 38 39 uint64_t result = 0; 40 for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 41 GOTPLTEntry* got = &(llvm::cast<GOTPLTEntry>((*it))); 42 *buffer = static_cast<uint32_t>(got->getValue()); 43 result += got->size(); 44 } 45 return result; 46} 47 48Fragment* MipsGOTPLT::consume() { 49 ++m_Last; 50 assert(m_Last != m_SectionData->end() && 51 "There is no reserved GOTPLT entries"); 52 return &(*m_Last); 53} 54 55bool MipsGOTPLT::hasGOT1() const { 56 return m_SectionData->size() > MipsGOTPLT0Num; 57} 58 59uint64_t MipsGOTPLT::getEntryAddr(size_t num) const { 60 return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; 61} 62 63void MipsGOTPLT::applyAllGOTPLT(uint64_t pltAddr) { 64 iterator it = begin(); 65 llvm::cast<GOTPLTEntry>(*it++).setValue(0); // PLT lazy resolver 66 llvm::cast<GOTPLTEntry>(*it++).setValue(0); // Module pointer 67 68 for (; it != end(); ++it) 69 llvm::cast<GOTPLTEntry>(*it).setValue(pltAddr); 70} 71 72} // namespace mcld 73