1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- MipsGOTPLT.cpp -----------------------------------------------------===// 2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// The MCLinker Project 4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source 6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details. 7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 9f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h> 10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include "MipsGOTPLT.h" 11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 12f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesnamespace { 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines typedef mcld::GOT::Entry<4> GOTPLTEntry; 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const size_t MipsGOTPLT0Num = 2; 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesnamespace mcld { 19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// MipsGOTPLT 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesMipsGOTPLT::MipsGOTPLT(LDSection& pSection) 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : GOT(pSection) 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Create header's entries. 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines new GOTPLTEntry(0, m_SectionData); 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines new GOTPLTEntry(0, m_SectionData); 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Last = ++m_SectionData->begin(); 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid MipsGOTPLT::reserve(size_t pNum) 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (size_t i = 0; i < pNum; i++) 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines new GOTPLTEntry(0, m_SectionData); 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOTPLT::emit(MemoryRegion& pRegion) 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines GOTPLTEntry* got = &(llvm::cast<GOTPLTEntry>((*it))); 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result += got->size(); 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesFragment* MipsGOTPLT::consume() 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ++m_Last; 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines assert(m_Last != m_SectionData->end() && 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines "There is no reserved GOTPLT entries"); 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return &(*m_Last); 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool MipsGOTPLT::hasGOT1() const 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return m_SectionData->size() > MipsGOTPLT0Num; 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesuint64_t MipsGOTPLT::getEntryAddr(size_t num) const 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid MipsGOTPLT::applyAllGOTPLT(uint64_t pltAddr) 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines iterator it = begin(); 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<GOTPLTEntry>(*it++).setValue(0); // PLT lazy resolver 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<GOTPLTEntry>(*it++).setValue(0); // Module pointer 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (; it != end(); ++it) 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<GOTPLTEntry>(*it).setValue(pltAddr); 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} //end mcld namespace 80