/* Utility to load a file into the simulator.
   Copyright (C) 1997-2021 Free Software Foundation, Inc.

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/>.  */

/* This is a standalone loader, independent of the sim-basic.h machinery,
   as it is used by simulators that don't use it [though that doesn't mean
   to suggest that they shouldn't :-)].  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ansidecl.h"
#include <stdio.h> /* for NULL */
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>

#include "sim-basics.h"
#include "bfd.h"
#include "sim-utils.h"

#include "gdb/callback.h"
#include "gdb/remote-sim.h"

static void eprintf (host_callback *, const char *, ...);
static void xprintf (host_callback *, const char *, ...);
static void report_transfer_performance
  (host_callback *, unsigned long, time_t, time_t);
static void xprintf_bfd_vma (host_callback *, bfd_vma);

/* Load program PROG into the simulator using the function DO_LOAD.
   If PROG_BFD is non-NULL, the file has already been opened.
   If VERBOSE_P is non-zero statistics are printed of each loaded section
   and the transfer rate (for consistency with gdb).
   If LMA_P is non-zero the program sections are loaded at the LMA
   rather than the VMA
   If this fails an error message is printed and NULL is returned.
   If it succeeds the bfd is returned.
   NOTE: For historical reasons, older hardware simulators incorrectly
   write the program sections at LMA interpreted as a virtual address.
   This is still accommodated for backward compatibility reasons. */


bfd *
sim_load_file (SIM_DESC sd, const char *myname, host_callback *callback,
	       const char *prog, bfd *prog_bfd, int verbose_p, int lma_p,
	       sim_write_fn do_write)
{
  asection *s;
  /* Record separately as we don't want to close PROG_BFD if it was passed.  */
  bfd *result_bfd;
  time_t start_time = 0;	/* Start and end times of download */
  time_t end_time = 0;
  unsigned long data_count = 0;	/* Number of bytes transferred to memory */
  int found_loadable_section;

  if (prog_bfd != NULL)
    result_bfd = prog_bfd;
  else
    {
      result_bfd = bfd_openr (prog, 0);
      if (result_bfd == NULL)
	{
	  eprintf (callback, "%s: can't open \"%s\": %s\n",
		   myname, prog, bfd_errmsg (bfd_get_error ()));
	  return NULL;
	}
    }

  if (!bfd_check_format (result_bfd, bfd_object))
    {
      eprintf (callback, "%s: \"%s\" is not an object file: %s\n",
	       myname, prog, bfd_errmsg (bfd_get_error ()));
      /* Only close if we opened it.  */
      if (prog_bfd == NULL)
	bfd_close (result_bfd);
      return NULL;
    }

  if (verbose_p)
    start_time = time (NULL);

  found_loadable_section = 0;
  for (s = result_bfd->sections; s; s = s->next)
    {
      if (s->flags & SEC_LOAD)
	{
	  bfd_size_type size;

	  size = bfd_section_size (s);
	  if (size > 0)
	    {
	      unsigned char *buffer;
	      bfd_vma lma;

	      buffer = malloc (size);
	      if (buffer == NULL)
		{
		  eprintf (callback,
			   "%s: insufficient memory to load \"%s\"\n",
			   myname, prog);
		  /* Only close if we opened it.  */
		  if (prog_bfd == NULL)
		    bfd_close (result_bfd);
		  return NULL;
		}
	      if (lma_p)
		lma = bfd_section_lma (s);
	      else
		lma = bfd_section_vma (s);
	      if (verbose_p)
		{
		  xprintf (callback, "Loading section %s, size 0x%lx %s ",
			   bfd_section_name (s),
			   (unsigned long) size,
			   (lma_p ? "lma" : "vma"));
		  xprintf_bfd_vma (callback, lma);
		  xprintf (callback, "\n");
		}
	      data_count += size;
	      bfd_get_section_contents (result_bfd, s, buffer, 0, size);
	      do_write (sd, lma, buffer, size);
	      found_loadable_section = 1;
	      free (buffer);
	    }
	}
    }

  if (!found_loadable_section)
    {
      eprintf (callback,
	       "%s: no loadable sections \"%s\"\n",
	       myname, prog);
      return NULL;
    }

  if (verbose_p)
    {
      end_time = time (NULL);
      xprintf (callback, "Start address ");
      xprintf_bfd_vma (callback, bfd_get_start_address (result_bfd));
      xprintf (callback, "\n");
      report_transfer_performance (callback, data_count, start_time, end_time);
    }

  bfd_cache_close (result_bfd);

  return result_bfd;
}

static void
xprintf (host_callback *callback, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);

  (*callback->vprintf_filtered) (callback, fmt, ap);

  va_end (ap);
}

static void
eprintf (host_callback *callback, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);

  (*callback->evprintf_filtered) (callback, fmt, ap);

  va_end (ap);
}

/* Report how fast the transfer went. */

static void
report_transfer_performance (host_callback *callback, unsigned long data_count,
			     time_t start_time, time_t end_time)
{
  xprintf (callback, "Transfer rate: ");
  if (end_time != start_time)
    xprintf (callback, "%ld bits/sec",
	     (data_count * 8) / (end_time - start_time));
  else
    xprintf (callback, "%ld bits in <1 sec", (data_count * 8));
  xprintf (callback, ".\n");
}

/* Print a bfd_vma.
   This is intended to handle the vagaries of 32 vs 64 bits, etc.  */

static void
xprintf_bfd_vma (host_callback *callback, bfd_vma vma)
{
  /* FIXME: for now */
  xprintf (callback, "0x%lx", (unsigned long) vma);
}
