//===- MipsGOTPLT.cpp -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "MipsGOTPLT.h" #include namespace { typedef mcld::GOT::Entry<4> GOTPLTEntry; const size_t MipsGOTPLT0Num = 2; } namespace mcld { //===----------------------------------------------------------------------===// // MipsGOTPLT //===----------------------------------------------------------------------===// MipsGOTPLT::MipsGOTPLT(LDSection& pSection) : GOT(pSection) { // Create header's entries. new GOTPLTEntry(0, m_SectionData); new GOTPLTEntry(0, m_SectionData); } uint64_t MipsGOTPLT::emit(MemoryRegion& pRegion) { uint32_t* buffer = reinterpret_cast(pRegion.begin()); uint64_t result = 0; for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { GOTPLTEntry* got = &(llvm::cast((*it))); *buffer = static_cast(got->getValue()); result += got->size(); } return result; } Fragment* MipsGOTPLT::create() { return new GOTPLTEntry(0, m_SectionData); } bool MipsGOTPLT::hasGOT1() const { return m_SectionData->size() > MipsGOTPLT0Num; } uint64_t MipsGOTPLT::getEntryAddr(size_t num) const { return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize; } void MipsGOTPLT::applyAllGOTPLT(uint64_t pltAddr) { iterator it = begin(); llvm::cast(*it++).setValue(0); // PLT lazy resolver llvm::cast(*it++).setValue(0); // Module pointer for (; it != end(); ++it) llvm::cast(*it).setValue(pltAddr); } } // namespace mcld