Home | History | Annotate | Download | only in Mips
      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 
     13 namespace {
     14 typedef mcld::GOT::Entry<4> GOTPLTEntry;
     15 
     16 const size_t MipsGOTPLT0Num = 2;
     17 }
     18 
     19 namespace mcld {
     20 
     21 //===----------------------------------------------------------------------===//
     22 // MipsGOTPLT
     23 //===----------------------------------------------------------------------===//
     24 MipsGOTPLT::MipsGOTPLT(LDSection& pSection) : GOT(pSection) {
     25   // Create header's entries.
     26   new GOTPLTEntry(0, m_SectionData);
     27   new GOTPLTEntry(0, m_SectionData);
     28 }
     29 
     30 uint64_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 
     42 Fragment* MipsGOTPLT::create() {
     43   return new GOTPLTEntry(0, m_SectionData);
     44 }
     45 
     46 bool MipsGOTPLT::hasGOT1() const {
     47   return m_SectionData->size() > MipsGOTPLT0Num;
     48 }
     49 
     50 uint64_t MipsGOTPLT::getEntryAddr(size_t num) const {
     51   return addr() + (MipsGOTPLT0Num + num) * GOTPLTEntry::EntrySize;
     52 }
     53 
     54 void 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