Home | History | Annotate | Download | only in Mips
      1 //===- MipsGOT.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 
     10 #include "MipsGOT.h"
     11 
     12 #include <llvm/Support/Casting.h>
     13 
     14 #include <mcld/LD/ResolveInfo.h>
     15 #include <mcld/Support/MemoryRegion.h>
     16 #include <mcld/Support/MsgHandling.h>
     17 
     18 namespace {
     19   const size_t MipsGOT0Num = 1;
     20 }
     21 
     22 using namespace mcld;
     23 
     24 //===----------------------------------------------------------------------===//
     25 // MipsGOT
     26 //===----------------------------------------------------------------------===//
     27 MipsGOT::MipsGOT(LDSection& pSection)
     28   : GOT(pSection),
     29     m_pLocalNum(0),
     30     m_pLast(NULL)
     31 {
     32   // Create GOT0 entries.
     33   reserve(MipsGOT0Num);
     34 
     35   // Skip GOT0 entries.
     36   iterator it = m_SectionData->begin();
     37 
     38   for (size_t i = 1; i < MipsGOT0Num; ++i) {
     39     assert((it != m_SectionData->end()) &&
     40            "Generation of GOT0 entries is incomplete!");
     41 
     42     ++it;
     43   }
     44 
     45   m_LocalGOTIterator = it;
     46   m_GlobalGOTIterator = it;
     47   m_pLocalNum = MipsGOT0Num;
     48 }
     49 
     50 void MipsGOT::reserve(size_t pNum)
     51 {
     52   for (size_t i = 0; i < pNum; i++) {
     53     new MipsGOTEntry(0, m_SectionData);
     54   }
     55 }
     56 
     57 MipsGOTEntry* MipsGOT::consume()
     58 {
     59   if (NULL == m_pLast) {
     60     assert(!empty() && "Consume empty GOT entry!");
     61     m_pLast = llvm::cast<MipsGOTEntry>(&m_SectionData->front());
     62     return m_pLast;
     63   }
     64 
     65   m_pLast = llvm::cast<MipsGOTEntry>(m_pLast->getNextNode());
     66   return m_pLast;
     67 }
     68 
     69 bool MipsGOT::hasGOT1() const
     70 {
     71   return (m_SectionData->size() > MipsGOT0Num);
     72 }
     73 
     74 uint64_t MipsGOT::emit(MemoryRegion& pRegion)
     75 {
     76   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
     77 
     78   uint64_t result = 0;
     79   for (iterator it = begin(), ie = end();
     80        it != ie; ++it, ++buffer) {
     81     MipsGOTEntry* got = &(llvm::cast<MipsGOTEntry>((*it)));
     82     *buffer = static_cast<uint32_t>(got->getValue());
     83     result += got->size();
     84   }
     85   return result;
     86 }
     87 
     88 void MipsGOT::reserveLocalEntry()
     89 {
     90   reserve(1);
     91   ++m_pLocalNum;
     92 
     93   // Move global entries iterator forward.
     94   // We need to put global GOT entries after all local ones.
     95   ++m_GlobalGOTIterator;
     96 }
     97 
     98 void MipsGOT::reserveGlobalEntry()
     99 {
    100   reserve(1);
    101 }
    102 
    103 MipsGOTEntry* MipsGOT::consumeLocal()
    104 {
    105   iterator& it = m_LocalGOTIterator;
    106   ++it;
    107   assert(it != m_SectionData->getFragmentList().end() &&
    108          "The number of GOT Entries and ResolveInfo doesn't match");
    109   return llvm::cast<MipsGOTEntry>(&(*it));
    110 }
    111 
    112 MipsGOTEntry* MipsGOT::consumeGlobal()
    113 {
    114   iterator& it = m_GlobalGOTIterator;
    115   ++it;
    116   assert(it != m_SectionData->getFragmentList().end() &&
    117          "The number of GOT Entries and ResolveInfo doesn't match");
    118   return llvm::cast<MipsGOTEntry>(&(*it));
    119 }
    120 
    121 size_t MipsGOT::getTotalNum() const
    122 {
    123   return m_SectionData->getFragmentList().size();
    124 }
    125 
    126 size_t MipsGOT::getLocalNum() const
    127 {
    128   return m_pLocalNum;
    129 }
    130 
    131