/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include "util.h"
#include "HeapMap.h"

#define HEAPCHUNKSZ     1024 // number of HeapObj's in a chunk
#define HEAPCHAINS      9192 // number of address-based chains
#define hash(x)         (((x) >> 6) % HEAPCHAINS)

typedef struct HeapObj
{
  uint64_t addr;
  uint64_t size;
  long val;
  HeapObj *next;
} HeapObj;

typedef struct HeapChunk
{
  void *addr;
  HeapChunk *next;
} HeapChunk;

HeapMap::HeapMap ()
{
  chunks = NULL;
  empty = NULL;
  chain = new HeapObj*[HEAPCHAINS];
  for (int i = 0; i < HEAPCHAINS; i++)
    chain[i] = NULL;

  mmaps = new HeapObj;
  mmaps->addr = (uint64_t) 0;
  mmaps->size = (uint64_t) 0;
  mmaps->val = -1;
  mmaps->next = NULL;
}

HeapMap::~HeapMap ()
{
  // free up all the chunks
  HeapChunk *c = chunks;
  while (c != NULL)
    {
      HeapChunk *next = c->next;
      delete c;
      c = next;
    }
  delete[] chain;
  delete mmaps;
}

void
HeapMap::allocate (uint64_t addr, long val)
{
  // get a HeapObj, and set it up for the allocated block
  HeapObj *incoming = getHeapObj ();
  incoming->addr = addr;
  incoming->val = val;
  incoming->next = NULL;

  // determine which chain the block belongs on
  int ichain = (int) hash (addr);

  // if this is the first, just set it up and return
  if (chain[ichain] == NULL)
    {
      chain[ichain] = incoming;
      return;
    }
  // chain is non-empty -- find the slot for this one
  //  chain is maintained in reverse address order
  HeapObj *prev = NULL;
  HeapObj *next = chain[ichain];

  for (;;)
    {
      if ((next == NULL) || (next->addr < incoming->addr))
	{
	  // we've found the spot
	  incoming->next = next;
	  if (prev == NULL)
	    chain[ichain] = incoming;
	  else
	    prev->next = incoming;
	  return;
	}
      if (next->addr == incoming->addr)
	{
	  // error -- two blocks with same address active
	  //   ignore the new one
	  releaseHeapObj (incoming);
	  return;
	}
      // not yet, keep looking
      prev = next;
      next = next->next;
    }
}

long
HeapMap::deallocate (uint64_t addr)
{
  int ichain = (int) hash (addr);
  HeapObj *cur = chain[ichain];
  HeapObj *prev = NULL;
  while (cur != NULL)
    {
      if (cur->addr == addr)
	{
	  // we've found the block
	  long val = cur->val;

	  // delete the block from the chain
	  if (prev == NULL)
	    chain[ichain] = cur->next;
	  else
	    prev->next = cur->next;
	  releaseHeapObj (cur);
	  return val;
	}
      prev = cur;
      cur = cur->next;
    }

  // block not found
  return 0;
}

void
HeapMap::allocateChunk ()
{
  // allocate the memory
  HeapChunk *c = new HeapChunk;
  HeapObj *newc = new HeapObj[HEAPCHUNKSZ];

  // set up the chunk, and queue it for destructor's use
  c->addr = (void *) newc;
  c->next = chunks;
  chunks = c;

  // Initialize the HeapObj's in the chunk to one chain
  // last entry is left NULL, terminating the chain
  for (int i = 0; i < (HEAPCHUNKSZ - 1); i++)
    newc[i].next = newc + i + 1;
  newc[HEAPCHUNKSZ - 1].next = NULL;

  // put that chain on the empty queue
  empty = newc;
}

HeapObj *
HeapMap::getHeapObj ()
{
  if (empty == NULL)
    allocateChunk ();
  HeapObj *ret = empty;
  empty = ret->next;
  return ret;
}

void
HeapMap::releaseHeapObj (HeapObj *obj)
{
  obj->next = empty;
  empty = obj;
}

UnmapChunk*
HeapMap::mmap (uint64_t addr, int64_t size, long val)
{
  HeapObj *incoming = getHeapObj ();
  incoming->addr = addr;
  incoming->size = size;
  incoming->val = val;
  incoming->next = NULL;
  UnmapChunk* list = process (incoming, addr, size);
  return list;
}

UnmapChunk*
HeapMap::munmap (uint64_t addr, int64_t size)
{
  UnmapChunk* list = process (NULL, addr, size);
  return list;
}

UnmapChunk*
HeapMap::process (HeapObj *obj, uint64_t addr, int64_t size)
{
  // Some graphics are used to clarify the alignment of mmap regions
  // obj, shown as consecutive pages: "NNNNNN"
  // cur, shown as consecutive pages: "CCCCCC"

  // Find the first overlap, start of N is before end of C.  Examples:
  //   CCCCC
  //     NNNNN
  // or
  //   CCCCC
  //    NNN
  // or
  //   CCCCC
  //  NNNNN
  // or
  //   CCCCC
  //  NNNNNNN
  HeapObj *prev = mmaps;
  HeapObj *cur = prev->next;
  while (cur)
    {
      if (addr < cur->addr + cur->size)
	break;
      prev = cur;
      cur = prev->next;
    }

  // None found
  if (cur == NULL)
    {
      prev->next = obj;
      return NULL;
    }

  UnmapChunk* list = NULL;
  if (addr > cur->addr)
    {
      if (cur->addr + cur->size <= addr + size)
	{
	  // Process overlap on the left (low side) of new allocation
	  // New range: N-start to C-end (gets freed below)
	  prev = cur;
	  cur = getHeapObj ();
	  cur->addr = addr;
	  cur->size = prev->addr + prev->size - addr;
	  cur->val = prev->val;
	  cur->next = prev->next;

	  // Truncate range: C-start to N-start
	  prev->size = addr - prev->addr;
	}
      else
	{
	  // Process new allocation that fits completely within old allocation
	  // New range: N-start to N-end (freed below)
	  int64_t c_end = cur->addr + cur->size;
	  prev = cur;
	  cur = getHeapObj ();
	  cur->addr = addr;
	  cur->size = size;
	  cur->val = prev->val;
	  cur->next = prev->next;

	  // Truncate range: C-start to N-start
	  prev->size = addr - prev->addr;

	  // New range: N-end to C-end.
	  HeapObj *next = getHeapObj ();
	  next->addr = addr + size;
	  next->size = c_end - next->addr;
	  next->val = cur->val;
	  next->next = cur->next;
	  cur->next = next;
	}
    }

  // Process all full overlaps.
  // Copy details of cur to UnmapChunk list, remove cur from mmaps
  while (cur && cur->addr + cur->size <= addr + size)
    {

      UnmapChunk* uc = new UnmapChunk;
      uc->val = cur->val;
      uc->size = cur->size;
      uc->next = list;
      list = uc;

      HeapObj *t = cur;
      cur = cur->next;
      releaseHeapObj (t);
    }

  if (cur && cur->addr < addr + size)
    {
      // Process the last overlap (right side of new allocation)
      // Copy details of cur to UnmapChunk list
      UnmapChunk* uc = new UnmapChunk;
      uc->val = cur->val;
      uc->size = addr + size - cur->addr;
      uc->next = list;
      list = uc;

      // Truncate left side of cur
      cur->size -= uc->size;
      cur->addr = addr + size;
    }

  // Insert new allocation
  if (obj)
    {
      prev->next = obj;
      obj->next = cur;
    }
  else
    prev->next = cur;
  return list;
}
