//===- MipsGOT.cpp --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <mcld/LD/ResolveInfo.h>
#include <mcld/Support/MemoryRegion.h>
#include <mcld/Support/MsgHandling.h>
#include "MipsGOT.h"

namespace {
  const size_t MipsGOTEntrySize = 4;
  const size_t MipsGOT0Num = 1;
}

using namespace mcld;

//===----------------------------------------------------------------------===//
// MipsGOT
MipsGOT::MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
  : GOT(pSection, pSectionData, MipsGOTEntrySize),
    m_pLocalNum(0)
{
  // Create GOT0 entries.
  for (size_t i = 0; i < MipsGOT0Num; ++i) {
    GOTEntry* entry =
      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);

    if (NULL == entry)
      fatal(diag::fail_allocate_memory) << "GOT0";

    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
  }

  // Skip GOT0 entries.
  iterator it = m_SectionData.begin();
  iterator ie = m_SectionData.end();

  for (size_t i = 1; i < MipsGOT0Num; ++i) {
    assert((it != ie) && "Generation of GOT0 entries is incomplete!");

    ++it;
  }

  m_LocalGOTIterator = it;
  m_GlobalGOTIterator = it;
  m_pLocalNum = MipsGOT0Num;
}

MipsGOT::iterator MipsGOT::begin()
{
  return m_SectionData.getFragmentList().begin();
}

MipsGOT::iterator MipsGOT::end()
{
  return m_SectionData.getFragmentList().end();
}

MipsGOT::const_iterator MipsGOT::begin() const
{
  return m_SectionData.getFragmentList().begin();
}

MipsGOT::const_iterator MipsGOT::end() const
{
  return m_SectionData.getFragmentList().end();
}

uint64_t MipsGOT::emit(MemoryRegion& pRegion)
{
  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());

  size_t entry_size = getEntrySize();

  uint64_t result = 0;
  for (iterator it = begin(), ie = end();
       it != ie; ++it, ++buffer) {
    GOTEntry* got = &(llvm::cast<GOTEntry>((*it)));
    *buffer = static_cast<uint32_t>(got->getContent());
    result += entry_size;
  }
  return result;
}

void MipsGOT::reserveEntry(size_t pNum)
{
  for (size_t i = 0; i < pNum; ++i) {
    GOTEntry* entry =
      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);

    if (NULL == entry)
      fatal(diag::fail_allocate_memory) << "GOTEntry";

    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
  }
}

void MipsGOT::reserveLocalEntry()
{
  reserveEntry(1);
  ++m_pLocalNum;

  // Move global entries iterator forward.
  // We need to put global GOT entries after all local ones.
  ++m_GlobalGOTIterator;
}

void MipsGOT::reserveGlobalEntry()
{
  reserveEntry(1);
}

GOTEntry* MipsGOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
{
  if (isLocal(&pInfo) && pInfo.type() == ResolveInfo::Section) {
    pExist = false;
    iterator& it = m_LocalGOTIterator;
    ++it;
    assert(it != m_SectionData.getFragmentList().end() &&
           "The number of GOT Entries and ResolveInfo doesn't match");
    GOTEntry* entry = llvm::cast<GOTEntry>(&(*it));
    return entry;
  }

  GOTEntry*& entry = m_GeneralGOTMap[&pInfo];

  pExist = NULL != entry;

  if (!pExist) {
    iterator& it = isLocal(&pInfo)  ? m_LocalGOTIterator : m_GlobalGOTIterator;

    ++it;

    assert(it != m_SectionData.getFragmentList().end() &&
           "The number of GOT Entries and ResolveInfo doesn't match");

    entry = llvm::cast<GOTEntry>(&(*it));
  }

  return entry;
}

size_t MipsGOT::getTotalNum() const
{
  return m_SectionData.getFragmentList().size();
}

size_t MipsGOT::getLocalNum() const
{
  return m_pLocalNum;
}

