//===- impl.cpp -----------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "X86GOT.h"
#include <mcld/LD/LDFileFormat.h>
#include <llvm/Support/ErrorHandling.h>
#include <new>

namespace {
  const size_t X86GOTEntrySize = 4;
}

using namespace mcld;

//===----------------------------------------------------------------------===//
// X86GOT
X86GOT::X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
             : GOT(pSection, pSectionData, X86GOTEntrySize),
               m_GeneralGOTNum(0), m_GOTPLTNum(0), m_GeneralGOTIterator(),
               m_GOTPLTIterator(), m_LastGOT0()
{
  GOTEntry* Entry = 0;

  // Create GOT0 entries.
  for (unsigned int i = 0; i < X86GOT0Num; i++) {
    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
                                        &m_SectionData);

    if (!Entry)
      llvm::report_fatal_error("Allocating GOT0 entries failed!");

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

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

  for (unsigned int i = 1; i < X86GOT0Num; ++i) {
    if (it == ie)
      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");

    ++it;
  }

  m_LastGOT0 = it;
  m_GeneralGOTIterator = it;
  m_GOTPLTIterator = it;
}

X86GOT::~X86GOT()
{
}

void X86GOT::reserveEntry(size_t pNum)
{
  GOTEntry* Entry = 0;

  for (size_t i = 0; i < pNum; i++) {
    Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
                                        &m_SectionData);

    if (!Entry)
      llvm::report_fatal_error("Allocating new memory for GOTEntry failed");

    m_Section.setSize(m_Section.size() + X86GOTEntrySize);
    ++m_GeneralGOTNum;
  }
}


GOTEntry* X86GOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
{
  GOTEntry *&Entry = m_GeneralGOTMap[&pInfo];
  pExist = 1;

  if (!Entry) {
    pExist = 0;

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

    Entry = llvm::cast<GOTEntry>(&(*m_GeneralGOTIterator));
  }

  return Entry;
}

void X86GOT::applyGOT0(uint64_t pAddress)
{
  llvm::cast<GOTEntry>
    (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
}

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

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

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

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

unsigned int X86GOT::getGOTPLTNum() const
{ return m_GOTPLTNum; }

X86GOT::iterator X86GOT::getLastGOT0()
{ return m_LastGOT0; }

const X86GOT::iterator X86GOT::getLastGOT0() const
{ return m_LastGOT0; }
