/* Parts of target interface that deal with accessing memory and memory-like
   objects.

   Copyright (C) 2006-2018 Free Software Foundation, Inc.

   This file is part of GDB.

   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 of the License, 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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "vec.h"
#include "target.h"
#include "memory-map.h"

#include "gdb_sys_time.h"
#include <algorithm>

static bool
compare_block_starting_address (const memory_write_request &a_req,
				const memory_write_request &b_req)
{
  return a_req.begin < b_req.begin;
}

/* Adds to RESULT all memory write requests from BLOCK that are
   in [BEGIN, END) range.

   If any memory request is only partially in the specified range,
   that part of the memory request will be added.  */

static void
claim_memory (const std::vector<memory_write_request> &blocks,
	      std::vector<memory_write_request> *result,
	      ULONGEST begin,
	      ULONGEST end)
{
  ULONGEST claimed_begin;
  ULONGEST claimed_end;

  for (const memory_write_request &r : blocks)
    {
      /* If the request doesn't overlap [BEGIN, END), skip it.  We
	 must handle END == 0 meaning the top of memory; we don't yet
	 check for R->end == 0, which would also mean the top of
	 memory, but there's an assertion in
	 target_write_memory_blocks which checks for that.  */

      if (begin >= r.end)
	continue;
      if (end != 0 && end <= r.begin)
	continue;

      claimed_begin = std::max (begin, r.begin);
      if (end == 0)
	claimed_end = r.end;
      else
	claimed_end = std::min (end, r.end);

      if (claimed_begin == r.begin && claimed_end == r.end)
	result->push_back (r);
      else
	{
	  struct memory_write_request n = r;

	  n.begin = claimed_begin;
	  n.end = claimed_end;
	  n.data += claimed_begin - r.begin;

	  result->push_back (n);
	}
    }
}

/* Given a vector of struct memory_write_request objects in BLOCKS,
   add memory requests for flash memory into FLASH_BLOCKS, and for
   regular memory to REGULAR_BLOCKS.  */

static void
split_regular_and_flash_blocks (const std::vector<memory_write_request> &blocks,
				std::vector<memory_write_request> *regular_blocks,
				std::vector<memory_write_request> *flash_blocks)
{
  struct mem_region *region;
  CORE_ADDR cur_address;

  /* This implementation runs in O(length(regions)*length(blocks)) time.
     However, in most cases the number of blocks will be small, so this does
     not matter.

     Note also that it's extremely unlikely that a memory write request
     will span more than one memory region, however for safety we handle
     such situations.  */

  cur_address = 0;
  while (1)
    {
      std::vector<memory_write_request> *r;

      region = lookup_mem_region (cur_address);
      r = region->attrib.mode == MEM_FLASH ? flash_blocks : regular_blocks;
      cur_address = region->hi;
      claim_memory (blocks, r, region->lo, region->hi);

      if (cur_address == 0)
	break;
    }
}

/* Given an ADDRESS, if BEGIN is non-NULL this function sets *BEGIN
   to the start of the flash block containing the address.  Similarly,
   if END is non-NULL *END will be set to the address one past the end
   of the block containing the address.  */

static void
block_boundaries (CORE_ADDR address, CORE_ADDR *begin, CORE_ADDR *end)
{
  struct mem_region *region;
  unsigned blocksize;
  CORE_ADDR offset_in_region;

  region = lookup_mem_region (address);
  gdb_assert (region->attrib.mode == MEM_FLASH);
  blocksize = region->attrib.blocksize;

  offset_in_region = address - region->lo;

  if (begin)
    *begin = region->lo + offset_in_region / blocksize * blocksize;
  if (end)
    *end = region->lo + (offset_in_region + blocksize - 1) / blocksize * blocksize;
}

/* Given the list of memory requests to be WRITTEN, this function
   returns write requests covering each group of flash blocks which must
   be erased.  */

static std::vector<memory_write_request>
blocks_to_erase (const std::vector<memory_write_request> &written)
{
  std::vector<memory_write_request> result;

  for (const memory_write_request &request : written)
    {
      CORE_ADDR begin, end;

      block_boundaries (request.begin, &begin, 0);
      block_boundaries (request.end - 1, 0, &end);

      if (!result.empty () && result.back ().end >= begin)
	result.back ().end = end;
      else
	result.emplace_back (begin, end);
    }

  return result;
}

/* Given ERASED_BLOCKS, a list of blocks that will be erased with
   flash erase commands, and WRITTEN_BLOCKS, the list of memory
   addresses that will be written, compute the set of memory addresses
   that will be erased but not rewritten (e.g. padding within a block
   which is only partially filled by "load").  */

static std::vector<memory_write_request>
compute_garbled_blocks (const std::vector<memory_write_request> &erased_blocks,
			const std::vector<memory_write_request> &written_blocks)
{
  std::vector<memory_write_request> result;

  unsigned j;
  unsigned je = written_blocks.size ();
  struct memory_write_request *erased_p;

  /* Look at each erased memory_write_request in turn, and
     see what part of it is subsequently written to.

     This implementation is O(length(erased) * length(written)).  If
     the lists are sorted at this point it could be rewritten more
     efficiently, but the complexity is not generally worthwhile.  */

  for (const memory_write_request &erased_iter : erased_blocks)
    {
      /* Make a deep copy -- it will be modified inside the loop, but
	 we don't want to modify original vector.  */
      struct memory_write_request erased = erased_iter;

      for (j = 0; j != je;)
	{
	  const memory_write_request *written = &written_blocks[j];

	  /* Now try various cases.  */

	  /* If WRITTEN is fully to the left of ERASED, check the next
	     written memory_write_request.  */
	  if (written->end <= erased.begin)
	    {
	      ++j;
	      continue;
	    }

	  /* If WRITTEN is fully to the right of ERASED, then ERASED
	     is not written at all.  WRITTEN might affect other
	     blocks.  */
	  if (written->begin >= erased.end)
	    {
	      result.push_back (erased);
	      goto next_erased;
	    }

	  /* If all of ERASED is completely written, we can move on to
	     the next erased region.  */
	  if (written->begin <= erased.begin
	      && written->end >= erased.end)
	    {
	      goto next_erased;
	    }

	  /* If there is an unwritten part at the beginning of ERASED,
	     then we should record that part and try this inner loop
	     again for the remainder.  */
	  if (written->begin > erased.begin)
	    {
	      result.emplace_back (erased.begin, written->begin);
	      erased.begin = written->begin;
	      continue;
	    }

	  /* If there is an unwritten part at the end of ERASED, we
	     forget about the part that was written to and wait to see
	     if the next write request writes more of ERASED.  We can't
	     push it yet.  */
	  if (written->end < erased.end)
	    {
	      erased.begin = written->end;
	      ++j;
	      continue;
	    }
	}

      /* If we ran out of write requests without doing anything about
	 ERASED, then that means it's really erased.  */
      result.push_back (erased);

    next_erased:
      ;
    }

  return result;
}

int
target_write_memory_blocks (const std::vector<memory_write_request> &requests,
			    enum flash_preserve_mode preserve_flash_p,
			    void (*progress_cb) (ULONGEST, void *))
{
  std::vector<memory_write_request> blocks = requests;
  struct memory_write_request *r;
  std::vector<memory_write_request> regular;
  std::vector<memory_write_request> flash;
  std::vector<memory_write_request> erased, garbled;

  /* END == 0 would represent wraparound: a write to the very last
     byte of the address space.  This file was not written with that
     possibility in mind.  This is fixable, but a lot of work for a
     rare problem; so for now, fail noisily here instead of obscurely
     later.  */
  for (const memory_write_request &iter : requests)
    gdb_assert (iter.end != 0);

  /* Sort the blocks by their start address.  */
  std::sort (blocks.begin (), blocks.end (), compare_block_starting_address);

  /* Split blocks into list of regular memory blocks,
     and list of flash memory blocks.  */
  split_regular_and_flash_blocks (blocks, &regular, &flash);

  /* If a variable is added to forbid flash write, even during "load",
     it should be checked here.  Similarly, if this function is used
     for other situations besides "load" in which writing to flash
     is undesirable, that should be checked here.  */

  /* Find flash blocks to erase.  */
  erased = blocks_to_erase (flash);

  /* Find what flash regions will be erased, and not overwritten; then
     either preserve or discard the old contents.  */
  garbled = compute_garbled_blocks (erased, flash);

  std::vector<gdb::unique_xmalloc_ptr<gdb_byte>> mem_holders;
  if (!garbled.empty ())
    {
      if (preserve_flash_p == flash_preserve)
	{
	  /* Read in regions that must be preserved and add them to
	     the list of blocks we read.  */
	  for (memory_write_request &iter : garbled)
	    {
	      gdb_assert (iter.data == NULL);
	      gdb::unique_xmalloc_ptr<gdb_byte> holder
		((gdb_byte *) xmalloc (iter.end - iter.begin));
	      iter.data = holder.get ();
	      mem_holders.push_back (std::move (holder));
	      int err = target_read_memory (iter.begin, iter.data,
					    iter.end - iter.begin);
	      if (err != 0)
		return err;

	      flash.push_back (iter);
	    }

	  std::sort (flash.begin (), flash.end (),
		     compare_block_starting_address);
	}
    }

  /* We could coalesce adjacent memory blocks here, to reduce the
     number of write requests for small sections.  However, we would
     have to reallocate and copy the data pointers, which could be
     large; large sections are more common in loadable objects than
     large numbers of small sections (although the reverse can be true
     in object files).  So, we issue at least one write request per
     passed struct memory_write_request.  The remote stub will still
     have the opportunity to batch flash requests.  */

  /* Write regular blocks.  */
  for (const memory_write_request &iter : regular)
    {
      LONGEST len;

      len = target_write_with_progress (current_top_target (),
					TARGET_OBJECT_MEMORY, NULL,
					iter.data, iter.begin,
					iter.end - iter.begin,
					progress_cb, iter.baton);
      if (len < (LONGEST) (iter.end - iter.begin))
	{
	  /* Call error?  */
	  return -1;
	}
    }

  if (!erased.empty ())
    {
      /* Erase all pages.  */
      for (const memory_write_request &iter : erased)
	target_flash_erase (iter.begin, iter.end - iter.begin);

      /* Write flash data.  */
      for (const memory_write_request &iter : flash)
	{
	  LONGEST len;

	  len = target_write_with_progress (current_top_target (),
					    TARGET_OBJECT_FLASH, NULL,
					    iter.data, iter.begin,
					    iter.end - iter.begin,
					    progress_cb, iter.baton);
	  if (len < (LONGEST) (iter.end - iter.begin))
	    error (_("Error writing data to flash"));
	}

      target_flash_done ();
    }

  return 0;
}
