//===- FragmentRef.cpp --------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Fragment/FragmentRef.h>

#include <cstring>
#include <cassert>

#include <llvm/Support/Casting.h>
#include <llvm/Support/ManagedStatic.h>

#include <mcld/Fragment/Fragment.h>
#include <mcld/LD/LDSection.h>
#include <mcld/LD/SectionData.h>
#include <mcld/LD/EhFrame.h>
#include <mcld/Support/GCFactory.h>
#include <mcld/Support/MemoryRegion.h>
#include <mcld/Fragment/RegionFragment.h>
#include <mcld/Fragment/Stub.h>

using namespace mcld;

typedef GCFactory<FragmentRef, MCLD_SECTIONS_PER_INPUT> FragRefFactory;

static llvm::ManagedStatic<FragRefFactory> g_FragRefFactory;

FragmentRef FragmentRef::g_NullFragmentRef;

//===----------------------------------------------------------------------===//
// FragmentRef
//===----------------------------------------------------------------------===//
FragmentRef::FragmentRef()
  : m_pFragment(NULL), m_Offset(0) {
}

FragmentRef::FragmentRef(Fragment& pFrag,
                         FragmentRef::Offset pOffset)
  : m_pFragment(&pFrag), m_Offset(pOffset) {
}

/// Create - create a fragment reference for a given fragment.
///
/// @param pFrag - the given fragment
/// @param pOffset - the offset, can be larger than the fragment, but can not
///                  be larger than the section size.
/// @return if the offset is legal, return the fragment reference. Otherwise,
/// return NULL.
FragmentRef* FragmentRef::Create(Fragment& pFrag, uint64_t pOffset)
{
  int64_t offset = pOffset;
  Fragment* frag = &pFrag;

  while (NULL != frag) {
    offset -= frag->size();
    if (offset <= 0)
      break;
    frag = frag->getNextNode();
  }


  if (NULL == frag)
    return Null();

  FragmentRef* result = g_FragRefFactory->allocate();
  new (result) FragmentRef(*frag, offset + frag->size());

  return result;
}

FragmentRef* FragmentRef::Create(LDSection& pSection, uint64_t pOffset)
{
  SectionData* data = NULL;
  switch (pSection.kind()) {
    case LDFileFormat::Relocation:
      // No fragment reference refers to a relocation section
      break;
    case LDFileFormat::EhFrame:
      if (pSection.hasEhFrame())
        data = &pSection.getEhFrame()->getSectionData();
      break;
    default:
      data = pSection.getSectionData();
      break;
  }

  if (NULL == data || data->empty()) {
    return Null();
  }

  return Create(data->front(), pOffset);
}

void FragmentRef::Clear()
{
  g_FragRefFactory->clear();
}

FragmentRef* FragmentRef::Null()
{
  return &g_NullFragmentRef;
}

FragmentRef& FragmentRef::assign(const FragmentRef& pCopy)
{
  m_pFragment = const_cast<Fragment*>(pCopy.m_pFragment);
  m_Offset = pCopy.m_Offset;
  return *this;
}

FragmentRef& FragmentRef::assign(Fragment& pFrag, FragmentRef::Offset pOffset)
{
  m_pFragment = &pFrag;
  m_Offset = pOffset;
  return *this;
}

void FragmentRef::memcpy(void* pDest, size_t pNBytes, Offset pOffset) const
{
  // check if the offset is still in a legal range.
  if (NULL == m_pFragment)
    return;
  unsigned int total_offset = m_Offset + pOffset;
  switch(m_pFragment->getKind()) {
    case Fragment::Region: {
      RegionFragment* region_frag = static_cast<RegionFragment*>(m_pFragment);
      unsigned int total_length = region_frag->getRegion().size();
      if (total_length < (total_offset+pNBytes))
        pNBytes = total_length - total_offset;

      std::memcpy(pDest, region_frag->getRegion().getBuffer(total_offset), pNBytes);
      return;
    }
    case Fragment::Stub: {
      Stub* stub_frag = static_cast<Stub*>(m_pFragment);
      unsigned int total_length = stub_frag->size();
      if (total_length < (total_offset+pNBytes))
        pNBytes = total_length - total_offset;
      std::memcpy(pDest, stub_frag->getContent() + total_offset, pNBytes);
      return;
    }
    case Fragment::Alignment:
    case Fragment::Fillment:
    default:
      return;
  }
}

FragmentRef::Address FragmentRef::deref()
{
  if (NULL == m_pFragment)
    return NULL;
  Address base = NULL;
  switch(m_pFragment->getKind()) {
    case Fragment::Region:
      base = static_cast<RegionFragment*>(m_pFragment)->getRegion().getBuffer();
      break;
    case Fragment::Alignment:
    case Fragment::Fillment:
    default:
      return NULL;
  }
  return base + m_Offset;
}

FragmentRef::ConstAddress FragmentRef::deref() const
{
  if (NULL == m_pFragment)
    return NULL;
  ConstAddress base = NULL;
  switch(m_pFragment->getKind()) {
    case Fragment::Region:
      base = static_cast<const RegionFragment*>(m_pFragment)->getRegion().getBuffer();
      break;
    case Fragment::Alignment:
    case Fragment::Fillment:
    default:
      return NULL;
  }
  return base + m_Offset;
}

FragmentRef::Offset FragmentRef::getOutputOffset() const
{
  Offset result = 0;
  if (NULL != m_pFragment)
    result = m_pFragment->getOffset();
  return (result + m_Offset);
}

