OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [sysc/] [src/] [MemoryLoad.cpp] - Diff between revs 51 and 63

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 51 Rev 63
/* MemoryLoad.cpp -- Program load functions
/* MemoryLoad.cpp -- Program load functions
 
 
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2009 Julius Baxter, julius@orsoc.se
   Copyright (C) 2009 Julius Baxter, julius@orsoc.se
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   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
   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)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
/* This program is commented throughout in a fashion suitable for processing
/* This program is commented throughout in a fashion suitable for processing
   with Doxygen. */
   with Doxygen. */
 
 
/* System includes */
/* System includes */
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
 
 
#include "MemoryLoad.h"
#include "MemoryLoad.h"
#include "OrpsocMain.h"
#include "OrpsocMain.h"
 
 
 
 
//! Constructor for the ORPSoC memory loader class
//! Constructor for the ORPSoC memory loader class
 
 
//! Initializes various values
//! Initializes various values
 
 
//! @param[in] orpsoc  The SystemC Verilated ORPSoC instance
//! @param[in] orpsoc  The SystemC Verilated ORPSoC instance
//! @param[in] accessor  Accessor class for this Verilated ORPSoC model
//! @param[in] accessor  Accessor class for this Verilated ORPSoC model
 
 
MemoryLoad::MemoryLoad
MemoryLoad::MemoryLoad
(
(
 OrpsocAccess             *_accessor
 OrpsocAccess             *_accessor
 )
 )
{
{
  accessor = _accessor;
  accessor = _accessor;
}       // MemoryAccess ()
}       // MemoryAccess ()
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Copy a string with null termination
/*!Copy a string with null termination
 
 
   This function is very similar to strncpy, except it null terminates the
   This function is very similar to strncpy, except it null terminates the
   string. A global function also used by the CUC.
   string. A global function also used by the CUC.
 
 
   @param[in] dst  The destination string
   @param[in] dst  The destination string
   @param[in] src  The source string
   @param[in] src  The source string
   @param[in] n    Number of chars to copy EXCLUDING the null terminator
   @param[in] n    Number of chars to copy EXCLUDING the null terminator
                   (i.e. dst had better have room for n+1 chars)
                   (i.e. dst had better have room for n+1 chars)
 
 
   @return  A pointer to dst                                                 */
   @return  A pointer to dst                                                 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
char *
char *
MemoryLoad::strstrip (char       *dst,
MemoryLoad::strstrip (char       *dst,
                      const char *src,
                      const char *src,
                      int         n)
                      int         n)
{
{
  strncpy (dst, src, n);
  strncpy (dst, src, n);
  *(dst + n) = '\0';
  *(dst + n) = '\0';
 
 
  return  dst;
  return  dst;
 
 
}       /* strstrip () */
}       /* strstrip () */
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Translate logical to physical addresses for the loader
/*!Translate logical to physical addresses for the loader
 
 
   Used only by the simulator loader to translate logical addresses into
   Used only by the simulator loader to translate logical addresses into
   physical.  If loadcode() is called with valid @c virtphy_transl pointer to
   physical.  If loadcode() is called with valid @c virtphy_transl pointer to
   a table of translations then translate() performs translation otherwise
   a table of translations then translate() performs translation otherwise
   physical address is equal to logical.
   physical address is equal to logical.
 
 
   Currently NOT used
   Currently NOT used
 
 
   @param[in] laddr       Logical address
   @param[in] laddr       Logical address
   @param[in] breakpoint  Unused
   @param[in] breakpoint  Unused
 
 
   @return  The physical address                                             */
   @return  The physical address                                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 oraddr_t
 oraddr_t
MemoryLoad::translate (oraddr_t  laddr,
MemoryLoad::translate (oraddr_t  laddr,
           int      *breakpoint)
           int      *breakpoint)
{
{
  /*
  /*
  int i;
  int i;
 
 
  // No translation (i.e. when loading kernel into simulator)
  // No translation (i.e. when loading kernel into simulator)
  if (transl_table == 0)
  if (transl_table == 0)
    {
    {
      return laddr;
      return laddr;
    }
    }
 
 
  // Try to find our translation in the table.
  // Try to find our translation in the table.
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
    {
    {
      if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0))
      if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0))
        {
        {
          // Page modified
          // Page modified
          set_direct32 (transl_table + i + 8, -2, 0, 0);
          set_direct32 (transl_table + i + 8, -2, 0, 0);
          PRINTF ("found paddr=%" PRIx32 "\n",
          PRINTF ("found paddr=%" PRIx32 "\n",
                  eval_direct32 (transl_table + i + 4, 0, 0) |
                  eval_direct32 (transl_table + i + 4, 0, 0) |
                  (laddr & (PAGE_SIZE - 1)));
                  (laddr & (PAGE_SIZE - 1)));
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
        }
        }
    }
    }
 
 
  // Allocate new phy page for us.
  // Allocate new phy page for us.
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
    {
    {
      if (eval_direct32 (transl_table + i + 8, 0, 0) == 0)
      if (eval_direct32 (transl_table + i + 8, 0, 0) == 0)
        {
        {
          // VPN
          // VPN
          set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0);
          set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0);
          // PPN
          // PPN
          set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0);
          set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0);
          // Page modified
          // Page modified
          //set_direct32 (transl_table + i + 8, -2, 0, 0);
          //set_direct32 (transl_table + i + 8, -2, 0, 0);
          PRINTF ("newly allocated ppn=%" PRIx32 "\n",
          PRINTF ("newly allocated ppn=%" PRIx32 "\n",
                  eval_direct32 (transl_table + i + 4, 0, 0));
                  eval_direct32 (transl_table + i + 4, 0, 0));
          PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4);
          PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4);
          PRINTF ("newly allocated ofs=%" PRIxADDR "\n",
          PRINTF ("newly allocated ofs=%" PRIxADDR "\n",
                  (laddr & (PAGE_SIZE - 1)));
                  (laddr & (PAGE_SIZE - 1)));
          PRINTF ("newly allocated paddr=%" PRIx32 "\n",
          PRINTF ("newly allocated paddr=%" PRIx32 "\n",
                  eval_direct32 (transl_table + i + 4, 0,
                  eval_direct32 (transl_table + i + 4, 0,
                                 0) | (laddr & (PAGE_SIZE - 1)));
                                 0) | (laddr & (PAGE_SIZE - 1)));
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
        }
        }
    }
    }
 
 
  // If we come this far then all phy memory is used and we can't find our
  // If we come this far then all phy memory is used and we can't find our
     page nor allocate new page.
     page nor allocate new page.
  transl_error = 1;
  transl_error = 1;
  PRINTF ("can't translate %" PRIxADDR "\n", laddr);
  PRINTF ("can't translate %" PRIxADDR "\n", laddr);
  exit (1);
  exit (1);
 
 
  return  -1;
  return  -1;
  */
  */
  return 0;
  return 0;
 
 
}       /* translate() */
}       /* translate() */
 
 
#if IMM_STATS
#if IMM_STATS
 int
 int
MemoryLoad::bits (uint32_t val)
MemoryLoad::bits (uint32_t val)
{
{
  int i = 1;
  int i = 1;
  if (!val)
  if (!val)
    return 0;
    return 0;
  while (val != 0 && (int32_t) val != -1)
  while (val != 0 && (int32_t) val != -1)
    {
    {
      i++;
      i++;
      val = (int32_t) val >> 1;
      val = (int32_t) val >> 1;
    }
    }
  return i;
  return i;
}
}
 
 
 void
 void
MemoryLoad::check_insn (uint32_t insn)
MemoryLoad::check_insn (uint32_t insn)
{
{
  int insn_index = insn_decode (insn);
  int insn_index = insn_decode (insn);
  struct insn_op_struct *opd = op_start[insn_index];
  struct insn_op_struct *opd = op_start[insn_index];
  uint32_t data = 0;
  uint32_t data = 0;
  int dis = 0;
  int dis = 0;
  const char *name;
  const char *name;
  if (!insn || insn_index < 0)
  if (!insn || insn_index < 0)
    return;
    return;
  name = insn_name (insn_index);
  name = insn_name (insn_index);
  if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0)
  if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0)
    return;
    return;
 
 
  while (1)
  while (1)
    {
    {
      uint32_t tmp = 0 unsigned int nbits = 0;
      uint32_t tmp = 0 unsigned int nbits = 0;
      while (1)
      while (1)
        {
        {
          tmp |=
          tmp |=
            ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
            ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
            nbits;
            nbits;
          nbits += opd->data;
          nbits += opd->data;
          if (opd->type & OPTYPE_OP)
          if (opd->type & OPTYPE_OP)
            break;
            break;
          opd++;
          opd++;
        }
        }
 
 
      /* Do we have to sign extend? */
      /* Do we have to sign extend? */
      if (opd->type & OPTYPE_SIG)
      if (opd->type & OPTYPE_SIG)
        {
        {
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
          if (tmp & (1 << sbit))
          if (tmp & (1 << sbit))
            tmp |= 0xFFFFFFFF << sbit;
            tmp |= 0xFFFFFFFF << sbit;
        }
        }
      if (opd->type & OPTYPE_DIS)
      if (opd->type & OPTYPE_DIS)
        {
        {
          /* We have to read register later.  */
          /* We have to read register later.  */
          data += tmp;
          data += tmp;
          dis = 1;
          dis = 1;
        }
        }
      else
      else
        {
        {
          if (!(opd->type & OPTYPE_REG) || dis)
          if (!(opd->type & OPTYPE_REG) || dis)
            {
            {
              if (!dis)
              if (!dis)
                data = tmp;
                data = tmp;
              if (strcmp (name, "l.movhi") == 0)
              if (strcmp (name, "l.movhi") == 0)
                {
                {
                  movhi = data << 16;
                  movhi = data << 16;
                }
                }
              else
              else
                {
                {
                  data |= movhi;
                  data |= movhi;
                  //PRINTF ("%08x %s\n", data, name);
                  //PRINTF ("%08x %s\n", data, name);
                  if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY))
                  if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY))
                    {
                    {
                      bcnt[bits (data)][0]++;
                      bcnt[bits (data)][0]++;
                      bsum[0]++;
                      bsum[0]++;
                    }
                    }
                  else
                  else
                    {
                    {
                      if (strcmp (name, "l.bf") == 0
                      if (strcmp (name, "l.bf") == 0
                          || strcmp (name, "l.bnf") == 0)
                          || strcmp (name, "l.bnf") == 0)
                        {
                        {
                          bcnt[bits (data)][1]++;
                          bcnt[bits (data)][1]++;
                          bsum[1]++;
                          bsum[1]++;
                        }
                        }
                      else
                      else
                        {
                        {
                          bcnt[bits (data)][2]++;
                          bcnt[bits (data)][2]++;
                          bsum[2]++;
                          bsum[2]++;
                        }
                        }
                    }
                    }
                }
                }
            }
            }
          data = 0;
          data = 0;
          dis = 0;
          dis = 0;
        }
        }
      if (opd->type & OPTYPE_LAST)
      if (opd->type & OPTYPE_LAST)
        {
        {
          return;
          return;
        }
        }
      opd++;
      opd++;
    }
    }
}
}
#endif
#endif
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Add an instruction to the program
/*!Add an instruction to the program
 
 
  @note insn must be in big endian format
  @note insn must be in big endian format
 
 
  @param[in] address     The address to use
  @param[in] address     The address to use
  @param[in] insn        The instruction to add
  @param[in] insn        The instruction to add
  @param[in] breakpoint  Not used (it is passed to the translate() function,
  @param[in] breakpoint  Not used (it is passed to the translate() function,
                         which also does not use it.                         */
                         which also does not use it.                         */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 void
 void
MemoryLoad::addprogram (oraddr_t  address,
MemoryLoad::addprogram (oraddr_t  address,
            uint32_t  insn,
            uint32_t  insn,
            int      *breakpoint)
            int      *breakpoint)
{
{
 
 
  // Memory is word addressed, not byte, so /4 the address we get
  // Memory is word addressed, not byte, so /4 the address we get
  int vaddr = (int) address/4;  /*(!runtime.sim.filename) ? translate (address, breakpoint) :
  int vaddr = (int) address/4;  /*(!runtime.sim.filename) ? translate (address, breakpoint) :
                                  translate (freemem, breakpoint);
                                  translate (freemem, breakpoint);
                                  -- jb
                                  -- jb
                                */
                                */
  /* We can't have set_program32 functions since it is not gauranteed that the
  /* We can't have set_program32 functions since it is not gauranteed that the
     section we're loading is aligned on a 4-byte boundry */
     section we're loading is aligned on a 4-byte boundry */
  /*
  /*
  set_program8 (vaddr, (insn >> 24) & 0xff);
  set_program8 (vaddr, (insn >> 24) & 0xff);
  set_program8 (vaddr + 1, (insn >> 16) & 0xff);
  set_program8 (vaddr + 1, (insn >> 16) & 0xff);
  set_program8 (vaddr + 2, (insn >> 8) & 0xff);
  set_program8 (vaddr + 2, (insn >> 8) & 0xff);
  set_program8 (vaddr + 3, insn & 0xff);
  set_program8 (vaddr + 3, insn & 0xff);
  */
  */
  /* Use the whole-word write */
  /* Use the whole-word write */
  accessor->set_mem(vaddr, insn);
  accessor->set_mem(vaddr, insn);
  PRINTF("*  addprogram: addr 0x%.8x insn: 0x%.8x (conf: 0x%.8x)\n", vaddr, insn, accessor->get_mem(vaddr));
  PRINTF("*  addprogram: addr 0x%.8x insn: 0x%.8x (conf: 0x%.8x)\n", vaddr, insn, accessor->get_mem(vaddr));
 
 
 
 
#if IMM_STATS
#if IMM_STATS
  check_insn (insn);
  check_insn (insn);
#endif
#endif
 
 
  //if (runtime.sim.filename)
  //if (runtime.sim.filename)
  //{
  //{
  //freemem += insn_len (insn_decode (insn));
  //freemem += insn_len (insn_decode (insn));
  //}
  //}
  freemem += 4;
  freemem += 4;
 
 
}       /* addprogram () */
}       /* addprogram () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Load big-endian COFF file
/*!Load big-endian COFF file
 
 
   @param[in] filename  File to load
   @param[in] filename  File to load
   @param[in] sections  Number of sections in file                           */
   @param[in] sections  Number of sections in file                           */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 void
 void
MemoryLoad::readfile_coff (char  *filename,
MemoryLoad::readfile_coff (char  *filename,
               short  sections)
               short  sections)
{
{
  FILE *inputfs;
  FILE *inputfs;
  char inputbuf[4];
  char inputbuf[4];
  uint32_t insn;
  uint32_t insn;
  int32_t sectsize;
  int32_t sectsize;
  COFF_AOUTHDR coffaouthdr;
  COFF_AOUTHDR coffaouthdr;
  struct COFF_scnhdr coffscnhdr;
  struct COFF_scnhdr coffscnhdr;
  int len;
  int len;
  int firstthree = 0;
  int firstthree = 0;
  int breakpoint = 0;
  int breakpoint = 0;
 
 
  if (!(inputfs = fopen (filename, "r")))
  if (!(inputfs = fopen (filename, "r")))
    {
    {
      perror ("readfile_coff");
      perror ("readfile_coff");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fseek (inputfs, sizeof (COFF_FILHDR), SEEK_SET) == -1)
  if (fseek (inputfs, sizeof (COFF_FILHDR), SEEK_SET) == -1)
    {
    {
      fclose (inputfs);
      fclose (inputfs);
      perror ("readfile_coff");
      perror ("readfile_coff");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1)
  if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1)
    {
    {
      fclose (inputfs);
      fclose (inputfs);
      perror ("readfile_coff");
      perror ("readfile_coff");
      exit (1);
      exit (1);
    }
    }
 
 
  while (sections--)
  while (sections--)
    {
    {
      uint32_t scnhdr_pos =
      uint32_t scnhdr_pos =
        sizeof (COFF_FILHDR) + sizeof (coffaouthdr) +
        sizeof (COFF_FILHDR) + sizeof (coffaouthdr) +
        sizeof (struct COFF_scnhdr) * firstthree;
        sizeof (struct COFF_scnhdr) * firstthree;
      if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1)
      if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1)
        {
        {
          fclose (inputfs);
          fclose (inputfs);
          perror ("readfile_coff");
          perror ("readfile_coff");
          exit (1);
          exit (1);
        }
        }
      if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1)
      if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1)
        {
        {
          fclose (inputfs);
          fclose (inputfs);
          perror ("readfile_coff");
          perror ("readfile_coff");
          exit (1);
          exit (1);
        }
        }
      PRINTF ("Section: %s,", coffscnhdr.s_name);
      PRINTF ("Section: %s,", coffscnhdr.s_name);
      PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr));
      PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr));
      PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr));
      PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr));
      PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size));
      PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size));
      PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr));
      PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr));
 
 
      sectsize = COFF_LONG_H (coffscnhdr.s_size);
      sectsize = COFF_LONG_H (coffscnhdr.s_size);
      ++firstthree;
      ++firstthree;
 
 
      /* loading section */
      /* loading section */
      freemem = COFF_LONG_H (coffscnhdr.s_paddr);
      freemem = COFF_LONG_H (coffscnhdr.s_paddr);
      if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1)
      if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1)
        {
        {
          fclose (inputfs);
          fclose (inputfs);
          perror ("readfile_coff");
          perror ("readfile_coff");
          exit (1);
          exit (1);
        }
        }
      while (sectsize > 0
      while (sectsize > 0
             && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
             && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
        {
        {
          insn = COFF_LONG_H (inputbuf);
          insn = COFF_LONG_H (inputbuf);
          //len = insn_len (insn_decode (insn));
          //len = insn_len (insn_decode (insn));
          len = 4;
          len = 4;
          if (len == 2)
          if (len == 2)
            {
            {
              fseek (inputfs, -2, SEEK_CUR);
              fseek (inputfs, -2, SEEK_CUR);
            }
            }
 
 
          addprogram (freemem, insn, &breakpoint);
          addprogram (freemem, insn, &breakpoint);
          sectsize -= len;
          sectsize -= len;
        }
        }
    }
    }
  if (firstthree < 3)
  if (firstthree < 3)
    {
    {
      PRINTF ("One or more missing sections. At least");
      PRINTF ("One or more missing sections. At least");
      PRINTF (" three sections expected (.text, .data, .bss).\n");
      PRINTF (" three sections expected (.text, .data, .bss).\n");
      exit (1);
      exit (1);
    }
    }
  if (firstthree > 3)
  if (firstthree > 3)
    {
    {
      PRINTF ("Warning: one or more extra sections. These");
      PRINTF ("Warning: one or more extra sections. These");
      PRINTF (" sections were handled as .data sections.\n");
      PRINTF (" sections were handled as .data sections.\n");
    }
    }
 
 
  fclose (inputfs);
  fclose (inputfs);
  PRINTF ("Finished loading COFF.\n");
  PRINTF ("Finished loading COFF.\n");
  return;
  return;
 
 
}       /* readfile_coff () */
}       /* readfile_coff () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Load symbols from big-endian COFF file
/*!Load symbols from big-endian COFF file
 
 
   @param[in] filename  File to load
   @param[in] filename  File to load
   @param[in] symptr    Symbol pointer value
   @param[in] symptr    Symbol pointer value
   @param[in] syms      Symbols value                                        */
   @param[in] syms      Symbols value                                        */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 
 
 void
 void
MemoryLoad::readsyms_coff (char *filename, uint32_t symptr, uint32_t syms)
MemoryLoad::readsyms_coff (char *filename, uint32_t symptr, uint32_t syms)
{
{
  FILE *inputfs;
  FILE *inputfs;
  struct COFF_syment coffsymhdr;
  struct COFF_syment coffsymhdr;
  int count = 0;
  int count = 0;
  uint32_t nsyms = syms;
  uint32_t nsyms = syms;
  if (!(inputfs = fopen (filename, "r")))
  if (!(inputfs = fopen (filename, "r")))
    {
    {
      perror ("readsyms_coff");
      perror ("readsyms_coff");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fseek (inputfs, symptr, SEEK_SET) == -1)
  if (fseek (inputfs, symptr, SEEK_SET) == -1)
    {
    {
      fclose (inputfs);
      fclose (inputfs);
      perror ("readsyms_coff");
      perror ("readsyms_coff");
      exit (1);
      exit (1);
    }
    }
 
 
  while (syms--)
  while (syms--)
    {
    {
      int i, n;
      int i, n;
      if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
      if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
        {
        {
          fclose (inputfs);
          fclose (inputfs);
          perror ("readsyms_coff");
          perror ("readsyms_coff");
          exit (1);
          exit (1);
        }
        }
 
 
      n = (unsigned char) coffsymhdr.e_numaux[0];
      n = (unsigned char) coffsymhdr.e_numaux[0];
 
 
      /* check whether this symbol belongs to a section and is external
      /* check whether this symbol belongs to a section and is external
         symbol; ignore all others */
         symbol; ignore all others */
      if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0
      if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0
          && coffsymhdr.e_sclass[0] == C_EXT)
          && coffsymhdr.e_sclass[0] == C_EXT)
        {
        {
          if (*((uint32_t *) coffsymhdr.e.e.e_zeroes))
          if (*((uint32_t *) coffsymhdr.e.e.e_zeroes))
            {
            {
              if (strlen (coffsymhdr.e.e_name)
              if (strlen (coffsymhdr.e.e_name)
                  && strlen (coffsymhdr.e.e_name) < 9)
                  && strlen (coffsymhdr.e.e_name) < 9)
                add_label (COFF_LONG_H (coffsymhdr.e_value),
                add_label (COFF_LONG_H (coffsymhdr.e_value),
                           coffsymhdr.e.e_name);
                           coffsymhdr.e.e_name);
            }
            }
          else
          else
            {
            {
              uint32_t fpos = ftell (inputfs);
              uint32_t fpos = ftell (inputfs);
 
 
              if (fseek
              if (fseek
                  (inputfs,
                  (inputfs,
                   symptr + nsyms * COFF_SYMESZ +
                   symptr + nsyms * COFF_SYMESZ +
                   COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0)
                   COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0)
                {
                {
                  char tmp[33], *s = &tmp[0];
                  char tmp[33], *s = &tmp[0];
                  while (s != &tmp[32])
                  while (s != &tmp[32])
                    if ((*(s++) = fgetc (inputfs)) == 0)
                    if ((*(s++) = fgetc (inputfs)) == 0)
                      break;
                      break;
                  tmp[32] = 0;
                  tmp[32] = 0;
                  add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]);
                  add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]);
                }
                }
              fseek (inputfs, fpos, SEEK_SET);
              fseek (inputfs, fpos, SEEK_SET);
            }
            }
        }
        }
 
 
      for (i = 0; i < n; i++)
      for (i = 0; i < n; i++)
        if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
        if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
          {
          {
            fclose (inputfs);
            fclose (inputfs);
            perror ("readsyms_coff3");
            perror ("readsyms_coff3");
            exit (1);
            exit (1);
          }
          }
      syms -= n;
      syms -= n;
      count += n;
      count += n;
    }
    }
 
 
  fclose (inputfs);
  fclose (inputfs);
  PRINTF ("Finished loading symbols.\n");
  PRINTF ("Finished loading symbols.\n");
  return;
  return;
}
}
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read an ELF file
/*!Read an ELF file
 
 
   @param[in] filename  File to load                                         */
   @param[in] filename  File to load                                         */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 void
 void
MemoryLoad::readfile_elf (char *filename)
MemoryLoad::readfile_elf (char *filename)
{
{
 
 
  FILE *inputfs;
  FILE *inputfs;
  struct elf32_hdr elfhdr;
  struct elf32_hdr elfhdr;
  struct elf32_phdr *elf_phdata = NULL;
  struct elf32_phdr *elf_phdata = NULL;
  struct elf32_shdr *elf_spnt, *elf_shdata;
  struct elf32_shdr *elf_spnt, *elf_shdata;
  struct elf32_sym *sym_tbl = (struct elf32_sym *) 0;
  struct elf32_sym *sym_tbl = (struct elf32_sym *) 0;
  uint32_t syms = 0;
  uint32_t syms = 0;
  char *str_tbl = (char *) 0;
  char *str_tbl = (char *) 0;
  char *s_str = (char *) 0;
  char *s_str = (char *) 0;
  int breakpoint = 0;
  int breakpoint = 0;
  uint32_t inputbuf;
  uint32_t inputbuf;
  uint32_t padd;
  uint32_t padd;
  uint32_t insn;
  uint32_t insn;
  int i, j, sectsize, len;
  int i, j, sectsize, len;
 
 
  if (!(inputfs = fopen (filename, "r")))
  if (!(inputfs = fopen (filename, "r")))
    {
    {
      perror ("readfile_elf");
      perror ("readfile_elf");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1)
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1)
    {
    {
      perror ("readfile_elf");
      perror ("readfile_elf");
      exit (1);
      exit (1);
    }
    }
 
 
  if ((elf_shdata =
  if ((elf_shdata =
       (struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) *
       (struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) *
                                     ELF_SHORT_H (elfhdr.e_shnum))) == NULL)
                                     ELF_SHORT_H (elfhdr.e_shnum))) == NULL)
    {
    {
      perror ("readfile_elf");
      perror ("readfile_elf");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0)
  if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0)
    {
    {
      perror ("readfile_elf");
      perror ("readfile_elf");
      exit (1);
      exit (1);
    }
    }
 
 
  if (fread
  if (fread
      (elf_shdata,
      (elf_shdata,
       ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1,
       ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1,
       inputfs) != 1)
       inputfs) != 1)
    {
    {
      perror ("readfile_elf");
      perror ("readfile_elf");
      exit (1);
      exit (1);
    }
    }
 
 
  if (ELF_LONG_H (elfhdr.e_phoff))
  if (ELF_LONG_H (elfhdr.e_phoff))
    {
    {
      if ((elf_phdata =
      if ((elf_phdata =
           (struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) *
           (struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) *
                                         ELF_SHORT_H (elfhdr.e_phentsize))) ==
                                         ELF_SHORT_H (elfhdr.e_phentsize))) ==
          NULL)
          NULL)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
 
 
      if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0)
      if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
 
 
      if (fread
      if (fread
          (elf_phdata,
          (elf_phdata,
           ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize),
           ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize),
           1, inputfs) != 1)
           1, inputfs) != 1)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
    }
    }
 
 
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
       i++, elf_spnt++)
       i++, elf_spnt++)
    {
    {
 
 
      if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB)
      if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB)
        {
        {
          if (NULL != str_tbl)
          if (NULL != str_tbl)
            {
            {
              free (str_tbl);
              free (str_tbl);
            }
            }
 
 
          if ((str_tbl =
          if ((str_tbl =
               (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
               (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
 
 
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
              0)
              0)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
 
 
          if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
          if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
              1)
              1)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
        }
        }
      else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB)
      else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB)
        {
        {
 
 
          if (NULL != sym_tbl)
          if (NULL != sym_tbl)
            {
            {
              free (sym_tbl);
              free (sym_tbl);
            }
            }
 
 
          if ((sym_tbl =
          if ((sym_tbl =
               (struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size)))
               (struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size)))
              == NULL)
              == NULL)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
 
 
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
              0)
              0)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
 
 
          if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
          if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
              1)
              1)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              exit (1);
              exit (1);
            }
            }
 
 
          syms =
          syms =
            ELF_LONG_H (elf_spnt->sh_size) /
            ELF_LONG_H (elf_spnt->sh_size) /
            ELF_LONG_H (elf_spnt->sh_entsize);
            ELF_LONG_H (elf_spnt->sh_entsize);
        }
        }
    }
    }
 
 
  if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF)
  if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF)
    {
    {
      elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)];
      elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)];
 
 
      if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
      if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
 
 
      if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0)
      if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
 
 
      if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1)
      if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1)
        {
        {
          perror ("readfile_elf");
          perror ("readfile_elf");
          exit (1);
          exit (1);
        }
        }
    }
    }
 
 
 
 
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
       i++, elf_spnt++)
       i++, elf_spnt++)
    {
    {
 
 
      if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS)
      if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS)
          && (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC))
          && (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC))
        {
        {
 
 
          padd = ELF_LONG_H (elf_spnt->sh_addr);
          padd = ELF_LONG_H (elf_spnt->sh_addr);
          for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++)
          for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++)
            {
            {
              if (ELF_LONG_H (elf_phdata[j].p_offset) &&
              if (ELF_LONG_H (elf_phdata[j].p_offset) &&
                  ELF_LONG_H (elf_phdata[j].p_offset) <=
                  ELF_LONG_H (elf_phdata[j].p_offset) <=
                  ELF_LONG_H (elf_spnt->sh_offset)
                  ELF_LONG_H (elf_spnt->sh_offset)
                  && (ELF_LONG_H (elf_phdata[j].p_offset) +
                  && (ELF_LONG_H (elf_phdata[j].p_offset) +
                      ELF_LONG_H (elf_phdata[j].p_memsz)) >
                      ELF_LONG_H (elf_phdata[j].p_memsz)) >
                  ELF_LONG_H (elf_spnt->sh_offset))
                  ELF_LONG_H (elf_spnt->sh_offset))
                padd =
                padd =
                  ELF_LONG_H (elf_phdata[j].p_paddr) +
                  ELF_LONG_H (elf_phdata[j].p_paddr) +
                  ELF_LONG_H (elf_spnt->sh_offset) -
                  ELF_LONG_H (elf_spnt->sh_offset) -
                  ELF_LONG_H (elf_phdata[j].p_offset);
                  ELF_LONG_H (elf_phdata[j].p_offset);
            }
            }
 
 
 
 
 
 
          if (ELF_LONG_H (elf_spnt->sh_name) && s_str)
          if (ELF_LONG_H (elf_spnt->sh_name) && s_str)
            PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
            //PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
 
            printf("* Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
          else
          else
            PRINTF ("Section: noname,");
            //PRINTF ("Section: noname,");
          PRINTF (" vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr));
            printf ("* Section: noname,");
          PRINTF (" paddr: 0x%" PRIx32, padd);
          printf ("* vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr));
          PRINTF (" offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset));
          printf ("* paddr: 0x%" PRIx32, padd);
          PRINTF (" size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size));
          printf ("* offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset));
 
          printf ("* size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size));
 
 
          freemem = padd;
          freemem = padd;
          sectsize = ELF_LONG_H (elf_spnt->sh_size);
          sectsize = ELF_LONG_H (elf_spnt->sh_size);
 
 
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
              0)
              0)
            {
            {
              perror ("readfile_elf");
              perror ("readfile_elf");
              free (elf_phdata);
              free (elf_phdata);
              exit (1);
              exit (1);
            }
            }
 
 
          while (sectsize > 0
          while (sectsize > 0
                 && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
                 && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
            {
            {
              insn = ELF_LONG_H (inputbuf);
              insn = ELF_LONG_H (inputbuf);
              //PRINTF("* addprogram(%.8x, %.8x, %d)\n", freemem, insn, breakpoint);
              //PRINTF("* addprogram(%.8x, %.8x, %d)\n", freemem, insn, breakpoint);
              addprogram (freemem, insn, &breakpoint);
              addprogram (freemem, insn, &breakpoint);
              sectsize -= 4;
              sectsize -= 4;
            }
            }
        }
        }
    }
    }
 
 
  if (str_tbl)
  if (str_tbl)
    {
    {
      i = 0;
      i = 0;
      while (syms--)
      while (syms--)
        {
        {
          if (sym_tbl[i].st_name && sym_tbl[i].st_info
          if (sym_tbl[i].st_name && sym_tbl[i].st_info
              && ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000)
              && ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000)
            {
            {
              add_label (ELF_LONG_H (sym_tbl[i].st_value),
              add_label (ELF_LONG_H (sym_tbl[i].st_value),
                         &str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]);
                         &str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]);
            }
            }
          i++;
          i++;
        }
        }
    }
    }
 
 
  if (NULL != str_tbl)
  if (NULL != str_tbl)
    {
    {
      free (str_tbl);
      free (str_tbl);
    }
    }
 
 
  if (NULL != sym_tbl)
  if (NULL != sym_tbl)
    {
    {
      free (sym_tbl);
      free (sym_tbl);
    }
    }
 
 
  free (s_str);
  free (s_str);
  free (elf_phdata);
  free (elf_phdata);
  free (elf_shdata);
  free (elf_shdata);
 
 
}
}
 
 
/* Identify file type and call appropriate readfile_X routine. It only
/* Identify file type and call appropriate readfile_X routine. It only
handles orX-coff-big executables at the moment. */
handles orX-coff-big executables at the moment. */
 
 
void
void
MemoryLoad::identifyfile (char *filename)
MemoryLoad::identifyfile (char *filename)
{
{
  FILE *inputfs;
  FILE *inputfs;
  COFF_FILHDR coffhdr;
  COFF_FILHDR coffhdr;
  struct elf32_hdr elfhdr;
  struct elf32_hdr elfhdr;
 
 
  if (!(inputfs = fopen (filename, "r")))
  if (!(inputfs = fopen (filename, "r")))
    {
    {
      perror (filename);
      perror (filename);
      fflush (stdout);
      fflush (stdout);
      fflush (stderr);
      fflush (stderr);
      exit (1);
      exit (1);
    }
    }
 
 
  if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1)
  if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1)
    {
    {
      if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a)
      if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a)
        {
        {
          uint32_t opthdr_size;
          uint32_t opthdr_size;
          PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic));
          PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic));
          PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags));
          PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags));
          PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr));
          PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr));
          if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC)
          if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC)
            {
            {
              PRINTF ("This COFF is not an executable.\n");
              PRINTF ("This COFF is not an executable.\n");
              exit (1);
              exit (1);
            }
            }
          opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr);
          opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr);
          if (opthdr_size != sizeof (COFF_AOUTHDR))
          if (opthdr_size != sizeof (COFF_AOUTHDR))
            {
            {
              PRINTF ("COFF optional header is missing or not recognized.\n");
              PRINTF ("COFF optional header is missing or not recognized.\n");
              PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size);
              PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size);
              exit (1);
              exit (1);
            }
            }
          fclose (inputfs);
          fclose (inputfs);
          readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns));
          readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns));
          readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr),
          readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr),
                         COFF_LONG_H (coffhdr.f_nsyms));
                         COFF_LONG_H (coffhdr.f_nsyms));
          return;
          return;
        }
        }
      else
      else
        {
        {
          PRINTF ("Not COFF file format\n");
          PRINTF ("Not COFF file format\n");
          fseek (inputfs, 0, SEEK_SET);
          fseek (inputfs, 0, SEEK_SET);
        }
        }
    }
    }
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1)
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1)
    {
    {
      if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45
      if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45
          && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46)
          && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46)
        {
        {
          PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type));
          PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type));
          PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine));
          PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine));
          PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version));
          PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version));
          PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum));
          PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum));
          if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC)
          if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC)
            {
            {
              PRINTF ("This ELF is not an executable.\n");
              PRINTF ("This ELF is not an executable.\n");
              exit (1);
              exit (1);
            }
            }
          fclose (inputfs);
          fclose (inputfs);
          readfile_elf (filename);
          readfile_elf (filename);
          return;
          return;
        }
        }
      else
      else
        {
        {
          PRINTF ("Not ELF file format.\n");
          PRINTF ("Not ELF file format.\n");
          fseek (inputfs, 0, SEEK_SET);
          fseek (inputfs, 0, SEEK_SET);
        }
        }
    }
    }
 
 
  perror ("identifyfile2");
  perror ("identifyfile2");
  fclose (inputfs);
  fclose (inputfs);
 
 
  return;
  return;
}
}
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Load file to memory
/*!Load file to memory
 
 
   Loads file to memory starting at address startaddr and returns freemem.
   Loads file to memory starting at address startaddr and returns freemem.
 
 
   @param[in] filename        File to load
   @param[in] filename        File to load
   @param[in] startaddr       Start address at which to load
   @param[in] startaddr       Start address at which to load
   @param[in] virtphy_transl  Virtual to physical transation table if
   @param[in] virtphy_transl  Virtual to physical transation table if
                              required. Only used for microkernel simulation,
                              required. Only used for microkernel simulation,
                              and not used in Ork1sim at present (set to NULL)
                              and not used in Ork1sim at present (set to NULL)
 
 
   @return  zero on success, negative on failure.                            */
   @return  zero on success, negative on failure.                            */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
uint32_t
uint32_t
MemoryLoad::loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
MemoryLoad::loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
{
{
  //int breakpoint = 0;
  //int breakpoint = 0;
 
 
  init_labels (); // jb
  init_labels (); // jb
 
 
  transl_error = 0;
  transl_error = 0;
  transl_table = virtphy_transl;
  transl_table = virtphy_transl;
  freemem      = startaddr;
  freemem      = startaddr;
  PRINTF ("*  MemoryLoad::loadcode: filename %s  startaddr=%" PRIxADDR "  virtphy_transl=%"
  PRINTF ("*  MemoryLoad::loadcode: filename %s  startaddr=%" PRIxADDR "  virtphy_transl=%"
          PRIxADDR "\n", filename, startaddr, virtphy_transl);
          PRIxADDR "\n", filename, startaddr, virtphy_transl);
  identifyfile (filename);
  identifyfile (filename);
 
 
#if IMM_STATS
#if IMM_STATS
  {
  {
    int i = 0, a = 0, b = 0, c = 0;
    int i = 0, a = 0, b = 0, c = 0;
    PRINTF ("index:arith/branch/jump\n");
    PRINTF ("index:arith/branch/jump\n");
    for (i = 0; i < 33; i++)
    for (i = 0; i < 33; i++)
      PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i,
      PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i,
              100. * (a += bcnt[i][0]) / bsum[0], 100. * (b +=
              100. * (a += bcnt[i][0]) / bsum[0], 100. * (b +=
                                                          bcnt[i][1]) /
                                                          bcnt[i][1]) /
              bsum[1], 100. * (c +=
              bsum[1], 100. * (c +=
                               bcnt[i][2]) / bsum[2], bcnt[i][0],
                               bcnt[i][2]) / bsum[2], bcnt[i][0],
              bcnt[i][1], bcnt[i][2]);
              bcnt[i][1], bcnt[i][2]);
    PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
    PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
  }
  }
#endif
#endif
 
 
  /*
  /*
  if (transl_error)
  if (transl_error)
    return -1;
    return -1;
  else
  else
    return translate (freemem, &breakpoint);
    return translate (freemem, &breakpoint);
  */
  */
  return (uint32_t) freemem;
  return (uint32_t) freemem;
 
 
}
}
 
 
/* From arch sim labels.c */
/* From arch sim labels.c */
void
void
MemoryLoad::init_labels ()
MemoryLoad::init_labels ()
{
{
  int i;
  int i;
  for (i = 0; i < LABELS_HASH_SIZE; i++)
  for (i = 0; i < LABELS_HASH_SIZE; i++)
    label_hash[i] = NULL;
    label_hash[i] = NULL;
}
}
 
 
void
void
MemoryLoad::add_label (oraddr_t addr, char *name)
MemoryLoad::add_label (oraddr_t addr, char *name)
{
{
  struct label_entry **tmp;
  struct label_entry **tmp;
  tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
  tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
  for (; *tmp; tmp = &((*tmp)->next));
  for (; *tmp; tmp = &((*tmp)->next));
  *tmp = (label_entry *) malloc (sizeof (**tmp));
  *tmp = (label_entry *) malloc (sizeof (**tmp));
  (*tmp)->name = (char *) malloc (strlen (name) + 1);
  (*tmp)->name = (char *) malloc (strlen (name) + 1);
  (*tmp)->addr = addr;
  (*tmp)->addr = addr;
  strcpy ((*tmp)->name, name);
  strcpy ((*tmp)->name, name);
  (*tmp)->next = NULL;
  (*tmp)->next = NULL;
}
}
 
 
struct label_entry *
struct label_entry *
MemoryLoad::get_label (oraddr_t addr)
MemoryLoad::get_label (oraddr_t addr)
{
{
  struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
  struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
  while (tmp)
  while (tmp)
    {
    {
      if (tmp->addr == addr)
      if (tmp->addr == addr)
        return tmp;
        return tmp;
      tmp = tmp->next;
      tmp = tmp->next;
    }
    }
  return NULL;
  return NULL;
}
}
 
 
struct label_entry *
struct label_entry *
MemoryLoad::find_label (char *name)
MemoryLoad::find_label (char *name)
{
{
  int i;
  int i;
  for (i = 0; i < LABELS_HASH_SIZE; i++)
  for (i = 0; i < LABELS_HASH_SIZE; i++)
    {
    {
      struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
      struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
      while (tmp)
      while (tmp)
        {
        {
          if (strcmp (tmp->name, name) == 0)
          if (strcmp (tmp->name, name) == 0)
            return tmp;
            return tmp;
          tmp = tmp->next;
          tmp = tmp->next;
        }
        }
    }
    }
  return NULL;
  return NULL;
}
}
 
 
/* Searches mem array for a particular label and returns label's address.
/* Searches mem array for a particular label and returns label's address.
   If label does not exist, returns 0. */
   If label does not exist, returns 0. */
oraddr_t
oraddr_t
MemoryLoad::eval_label (char *name)
MemoryLoad::eval_label (char *name)
{
{
  struct label_entry *le;
  struct label_entry *le;
  char *plus;
  char *plus;
  char *minus;
  char *minus;
  int positive_offset = 0;
  int positive_offset = 0;
  int negative_offset = 0;
  int negative_offset = 0;
 
 
  if ((plus = strchr (name, '+')))
  if ((plus = strchr (name, '+')))
    {
    {
      *plus = '\0';
      *plus = '\0';
      positive_offset = atoi (++plus);
      positive_offset = atoi (++plus);
    }
    }
 
 
  if ((minus = strchr (name, '-')))
  if ((minus = strchr (name, '-')))
    {
    {
      *minus = '\0';
      *minus = '\0';
      negative_offset = atoi (++minus);
      negative_offset = atoi (++minus);
    }
    }
  le = find_label (name);
  le = find_label (name);
  if (!le)
  if (!le)
    return 0;
    return 0;
 
 
  return le->addr + positive_offset - negative_offset;
  return le->addr + positive_offset - negative_offset;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.