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