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

   Copyright (C) 2006-2020 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 "target.h"
#include "memory-map.h"

#include "gdbsupport/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 ();

  /* 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;
  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;
}
