//===- Space.cpp ----------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Support/Space.h>
#include <mcld/Support/FileHandle.h>
#include <mcld/Support/MsgHandling.h>
#include <cstdlib>
#include <unistd.h>

using namespace mcld;

//===----------------------------------------------------------------------===//
// constant data
static const off_t PageSize = getpagesize();

//===----------------------------------------------------------------------===//
// Non-member functions
//===----------------------------------------------------------------------===//
//
// low address      A page             high address
// |--------------------|------------------|
// ^ page_offset        ^ pFileOffset      ^ page_boundary
//
// Given a file offset, return the page offset.
// return the first page boundary \b before pFileOffset
inline static off_t page_offset(off_t pFileOffset)
{ return pFileOffset & ~ (PageSize - 1); }

// page_boundary - Given a file size, return the size to read integral pages.
// return the first page boundary \b after pFileOffset
inline static off_t page_boundary(off_t pFileOffset)
{ return (pFileOffset + (PageSize - 1)) & ~ (PageSize - 1); }

inline static Space::Type policy(off_t pOffset, size_t pLength)
{
  const size_t threshold = (PageSize*3)/4; // 3/4 page size in Linux
  if (pLength < threshold)
    return Space::ALLOCATED_ARRAY;
  else
    return Space::MMAPED;
}

//===----------------------------------------------------------------------===//
// Space
//===----------------------------------------------------------------------===//
Space::Space()
  : m_Data(NULL), m_StartOffset(0), m_Size(0),
    m_RegionCount(0), m_Type(UNALLOCATED) {
}

Space::Space(Space::Type pType, void* pMemBuffer, size_t pSize)
  : m_Data(static_cast<Address>(pMemBuffer)), m_StartOffset(0), m_Size(pSize),
    m_RegionCount(0), m_Type(pType)
{
}

Space::~Space()
{
  // do nothing. m_Data is deleted by @ref releaseSpace
}

Space* Space::Create(void* pMemBuffer, size_t pSize)
{
  Space* result = new Space(EXTERNAL, pMemBuffer, pSize);
  return result;
}

Space* Space::Create(FileHandle& pHandler, size_t pStart, size_t pSize)
{
  Type type;
  void* memory = NULL;
  Space* result = NULL;
  size_t start = 0, size = 0, total_offset;
  switch(type = policy(pStart, pSize)) {
    case ALLOCATED_ARRAY: {
      // adjust total_offset, start and size
      total_offset = pStart + pSize;
      start = pStart;
      if (total_offset > pHandler.size()) {
        if (pHandler.isWritable()) {
          size = pSize;
          pHandler.truncate(total_offset);
        }
        else if (pHandler.size() > start)
          size = pHandler.size() - start;
        else {
          // create a space out of a read-only file.
          fatal(diag::err_cannot_read_small_file) << pHandler.path()
                                                  << pHandler.size()
                                                  << start << size;
        }
      }
      else
        size = pSize;

      // malloc
      memory = (void*)malloc(size);
      if (!pHandler.read(memory, start, size))
        error(diag::err_cannot_read_file) << pHandler.path() << start << size;

      break;
    }
    case MMAPED: {
      // adjust total_offset, start and size
      total_offset = page_boundary(pStart + pSize);
      start = page_offset(pStart);
      if (total_offset > pHandler.size()) {
        if (pHandler.isWritable()) {
          size = page_boundary((pStart - start) + pSize);
          pHandler.truncate(total_offset);
        }
        else if (pHandler.size() > start)
          size = pHandler.size() - start;
        else {
          // create a space out of a read-only file.
          fatal(diag::err_cannot_read_small_file) << pHandler.path()
                                                  << pHandler.size()
                                                  << start << size;
        }
      }
      else
        size = page_boundary((pStart - start) + pSize);

      // mmap
      if (!pHandler.mmap(memory, start, size))
        error(diag::err_cannot_mmap_file) << pHandler.path() << start << size;

      break;
    }
    default:
      break;
  } // end of switch

  result = new Space(type, memory, size);
  result->setStart(start);
  return result;
}

void Space::Destroy(Space*& pSpace)
{
  delete pSpace;
  pSpace = NULL;
}

void Space::Release(Space* pSpace, FileHandle& pHandler)
{
  if (NULL == pSpace)
    return;

  switch(pSpace->type()) {
    case ALLOCATED_ARRAY:
      free(pSpace->memory());
      break;
    case MMAPED:
      if (!pHandler.munmap(pSpace->memory(), pSpace->size()))
        error(diag::err_cannot_munmap_file) << pHandler.path();
      break;
    default: // external and unallocated memory buffers
      break;
  } // end of switch
}

void Space::Sync(Space* pSpace, FileHandle& pHandler)
{
  if (NULL == pSpace || !pHandler.isWritable())
    return;

  switch(pSpace->type()) {
    case Space::ALLOCATED_ARRAY: {
      if (!pHandler.write(pSpace->memory(),
                          pSpace->start(),
                          pSpace->size())) {
        error(diag::err_cannot_write_file) << pHandler.path()
                                           << pSpace->start()
                                           << pSpace->size();
      }
      return;
    }
    case Space::MMAPED:
    default: {
      // system will eventually write bakc the memory after
      // calling ::munmap
      return;
    }
  } // end of switch
}

