/* load.c --- loading object files into the RX simulator.

Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Red Hat, Inc.

This file is part of the GNU simulators.

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 "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "bfd.h"
#include "libbfd.h"
#include "cpu.h"
#include "mem.h"
#include "elf/internal.h"
#include "elf/common.h"

/* A note about endianness and swapping...

   The RX chip is CISC-like in that the opcodes are variable length
   and are read as a stream of bytes.  However, the chip itself shares
   the code prefetch block with the data fetch block, so when it's
   configured for big endian mode, the memory fetched for opcodes is
   word-swapped.  To compensate for this, the ELF file has the code
   sections pre-swapped.  Our BFD knows this, and for the convenience
   of all the other tools, hides this swapping at a very low level.
   I.e.  it swaps words on the way out and on the way back in.

   Fortunately the iovector routines are unaffected by this, so we
   can use them to read in the segments directly, without having
   to worry about byte swapping anything.

   However, our opcode decoder and disassemblers need to swap the data
   after reading it from the chip memory, just like the chip does.
   All in all, the code words are swapped four times between the
   assembler and our decoder.

   If the chip is running in little-endian mode, no swapping is done
   anywhere.  Note also that the *operands* within opcodes are always
   encoded in little-endian format.  */

void
rx_load (bfd *prog)
{
  unsigned long highest_addr_loaded = 0;
  Elf_Internal_Phdr * phdrs;
  long sizeof_phdrs;
  int num_headers;
  int i;

  rx_big_endian = bfd_big_endian (prog);

  /* Note we load by ELF program header not by BFD sections.
     This is because BFD sections get their information from
     the ELF section structure, which only includes a VMA value
     and not an LMA value.  */
  sizeof_phdrs = bfd_get_elf_phdr_upper_bound (prog);
  if (sizeof_phdrs == 0)
    {
      fprintf (stderr, "Failed to get size of program headers\n");
      return;
    }
  phdrs = malloc (sizeof_phdrs);
  if (phdrs == NULL)
    {
      fprintf (stderr, "Failed allocate memory to hold program headers\n");
      return;
    }
  num_headers = bfd_get_elf_phdrs (prog, phdrs);
  if (num_headers < 1)
    {
      fprintf (stderr, "Failed to read program headers\n");
      return;
    }
  
  for (i = 0; i < num_headers; i++)
    {
      Elf_Internal_Phdr * p = phdrs + i;
      char *buf;
      bfd_vma size;
      bfd_vma base;
      file_ptr offset;

      size = p->p_filesz;
      if (size <= 0)
	continue;

      base = p->p_paddr;
      if (verbose > 1)
	fprintf (stderr, "[load segment: lma=%08x vma=%08x size=%08x]\n",
		 (int) base, (int) p->p_vaddr, (int) size);

      buf = malloc (size);
      if (buf == NULL)
	{
	  fprintf (stderr, "Failed to allocate buffer to hold program segment\n");
	  continue;
	}
      
      offset = p->p_offset;
      if (prog->iovec->bseek (prog, offset, SEEK_SET) != 0)
	{
	  fprintf (stderr, "Failed to seek to offset %lx\n", (long) offset);
	  continue;
	}
      if (prog->iovec->bread (prog, buf, size) != size)
	{
	  fprintf (stderr, "Failed to read %lx bytes\n", size);
	  continue;
	}

      mem_put_blk (base, buf, size);
      free (buf);
      if (highest_addr_loaded < base + size - 1 && size >= 4)
	highest_addr_loaded = base + size - 1;
    }

  free (phdrs);

  regs.r_pc = prog->start_address;

  if (strcmp (bfd_get_target (prog), "srec") == 0
      || regs.r_pc == 0)
    {
      regs.r_pc = mem_get_si (0xfffffffc);
      heaptop = heapbottom = 0;
    }

  reset_decoder ();

  if (verbose > 1)
    fprintf (stderr, "[start pc=%08x %s]\n",
	     (unsigned int) regs.r_pc,
	     rx_big_endian ? "BE" : "LE");
}
