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} 29 30uint64_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 42Fragment* MipsGOTPLT::create() { 43 return new GOTPLTEntry(0, m_SectionData); 44} 45 46bool MipsGOTPLT::hasGOT1() const { 47 return m_SectionData->size() > MipsGOTPLT0Num; 48} 49 50uint64_t MipsGOTPLT::getEntryAddr(size_t num) const { 51 return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; 52} 53 54void 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