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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [gdbserver/] [low-sim.c] - Diff between revs 107 and 1765

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

Rev 107 Rev 1765
/* Low level interface to simulators, for the remote server for GDB.
/* Low level interface to simulators, for the remote server for GDB.
   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
#include "defs.h"
#include "defs.h"
#include "bfd.h"
#include "bfd.h"
#include "server.h"
#include "server.h"
#include "callback.h"           /* GDB simulator callback interface */
#include "callback.h"           /* GDB simulator callback interface */
#include "remote-sim.h"         /* GDB simulator interface */
#include "remote-sim.h"         /* GDB simulator interface */
 
 
extern int remote_debug;
extern int remote_debug;
 
 
extern host_callback default_callback;  /* in sim/common/callback.c */
extern host_callback default_callback;  /* in sim/common/callback.c */
 
 
static char my_registers[REGISTER_BYTES] __attribute__ ((aligned));
static char my_registers[REGISTER_BYTES] __attribute__ ((aligned));
char * registers = my_registers;
char * registers = my_registers;
 
 
int target_byte_order;          /* used by simulator */
int target_byte_order;          /* used by simulator */
 
 
/* We record the result of sim_open so we can pass it
/* We record the result of sim_open so we can pass it
   back to the other sim_foo routines.  */
   back to the other sim_foo routines.  */
static SIM_DESC gdbsim_desc = 0;
static SIM_DESC gdbsim_desc = 0;
 
 
/* This version of "load" should be usable for any simulator that
/* This version of "load" should be usable for any simulator that
   does not support loading itself.  */
   does not support loading itself.  */
 
 
static void
static void
generic_load (loadfile_bfd)
generic_load (loadfile_bfd)
     bfd *loadfile_bfd;
     bfd *loadfile_bfd;
{
{
  asection *s;
  asection *s;
 
 
  for (s = loadfile_bfd->sections; s; s = s->next)
  for (s = loadfile_bfd->sections; s; s = s->next)
    {
    {
      if (s->flags & SEC_LOAD)
      if (s->flags & SEC_LOAD)
        {
        {
          bfd_size_type size;
          bfd_size_type size;
 
 
          size = bfd_get_section_size_before_reloc (s);
          size = bfd_get_section_size_before_reloc (s);
          if (size > 0)
          if (size > 0)
            {
            {
              char *buffer;
              char *buffer;
              bfd_vma lma;      /* use load address, not virtual address */
              bfd_vma lma;      /* use load address, not virtual address */
 
 
              buffer = xmalloc (size);
              buffer = xmalloc (size);
              lma = s->lma;
              lma = s->lma;
 
 
              /* Is this really necessary?  I guess it gives the user something
              /* Is this really necessary?  I guess it gives the user something
                 to look at during a long download.  */
                 to look at during a long download.  */
              printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
              printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
                      bfd_get_section_name (loadfile_bfd, s),
                      bfd_get_section_name (loadfile_bfd, s),
                      (unsigned long) size,
                      (unsigned long) size,
                      (unsigned long) lma);     /* chops high 32 bits.  FIXME!! */
                      (unsigned long) lma);     /* chops high 32 bits.  FIXME!! */
 
 
              bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
              bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
 
 
              write_inferior_memory (lma, buffer, size);
              write_inferior_memory (lma, buffer, size);
              free (buffer);
              free (buffer);
            }
            }
        }
        }
    }
    }
 
 
  printf ("Start address 0x%lx\n",
  printf ("Start address 0x%lx\n",
          (unsigned long) loadfile_bfd->start_address);
          (unsigned long) loadfile_bfd->start_address);
 
 
  /* We were doing this in remote-mips.c, I suspect it is right
  /* We were doing this in remote-mips.c, I suspect it is right
     for other targets too.  */
     for other targets too.  */
  /* write_pc (loadfile_bfd->start_address); *//* FIXME!! */
  /* write_pc (loadfile_bfd->start_address); *//* FIXME!! */
}
}
 
 
int
int
create_inferior (program, argv)
create_inferior (program, argv)
     char *program;
     char *program;
     char **argv;
     char **argv;
{
{
  bfd *abfd;
  bfd *abfd;
  int pid = 0;
  int pid = 0;
#ifdef TARGET_BYTE_ORDER_SELECTABLE
#ifdef TARGET_BYTE_ORDER_SELECTABLE
  char **new_argv;
  char **new_argv;
  int nargs;
  int nargs;
#endif
#endif
 
 
  abfd = bfd_openr (program, 0);
  abfd = bfd_openr (program, 0);
  if (!abfd)
  if (!abfd)
    {
    {
      fprintf (stderr, "gdbserver: can't open %s: %s\n",
      fprintf (stderr, "gdbserver: can't open %s: %s\n",
               program, bfd_errmsg (bfd_get_error ()));
               program, bfd_errmsg (bfd_get_error ()));
      exit (1);
      exit (1);
    }
    }
 
 
  if (!bfd_check_format (abfd, bfd_object))
  if (!bfd_check_format (abfd, bfd_object))
    {
    {
      fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
      fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
               program, bfd_errmsg (bfd_get_error ()));
               program, bfd_errmsg (bfd_get_error ()));
      exit (1);
      exit (1);
    }
    }
 
 
#ifdef TARGET_BYTE_ORDER_SELECTABLE
#ifdef TARGET_BYTE_ORDER_SELECTABLE
  /* Add "-E big" or "-E little" to the argument list depending on the
  /* Add "-E big" or "-E little" to the argument list depending on the
     endianness of the program to be loaded.  */
     endianness of the program to be loaded.  */
  for (nargs = 0; argv[nargs] != NULL; nargs++)          /* count the args */
  for (nargs = 0; argv[nargs] != NULL; nargs++)          /* count the args */
    ;
    ;
  new_argv = alloca (sizeof (char *) * (nargs + 3));    /* allocate new args */
  new_argv = alloca (sizeof (char *) * (nargs + 3));    /* allocate new args */
  for (nargs = 0; argv[nargs] != NULL; nargs++)          /* copy old to new */
  for (nargs = 0; argv[nargs] != NULL; nargs++)          /* copy old to new */
    new_argv[nargs] = argv[nargs];
    new_argv[nargs] = argv[nargs];
  new_argv[nargs] = "-E";
  new_argv[nargs] = "-E";
  new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
  new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
  new_argv[nargs + 2] = NULL;
  new_argv[nargs + 2] = NULL;
  argv = new_argv;
  argv = new_argv;
#endif
#endif
 
 
  /* Create an instance of the simulator.  */
  /* Create an instance of the simulator.  */
  default_callback.init (&default_callback);
  default_callback.init (&default_callback);
  gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
  gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
  if (gdbsim_desc == 0)
  if (gdbsim_desc == 0)
    exit (1);
    exit (1);
 
 
  /* Load the program into the simulator.  */
  /* Load the program into the simulator.  */
  if (abfd)
  if (abfd)
    if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
    if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
      generic_load (abfd);
      generic_load (abfd);
 
 
  /* Create an inferior process in the simulator.  This initializes SP.  */
  /* Create an inferior process in the simulator.  This initializes SP.  */
  sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
  sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
  sim_resume (gdbsim_desc, 1, 0);        /* execute one instr */
  sim_resume (gdbsim_desc, 1, 0);        /* execute one instr */
  return pid;
  return pid;
}
}
 
 
/* Kill the inferior process.  Make us have no inferior.  */
/* Kill the inferior process.  Make us have no inferior.  */
 
 
void
void
kill_inferior ()
kill_inferior ()
{
{
  sim_close (gdbsim_desc, 0);
  sim_close (gdbsim_desc, 0);
  default_callback.shutdown (&default_callback);
  default_callback.shutdown (&default_callback);
}
}
 
 
/* Fetch one register.  */
/* Fetch one register.  */
 
 
static void
static void
fetch_register (regno)
fetch_register (regno)
     int regno;
     int regno;
{
{
  sim_fetch_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
  sim_fetch_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
                      REGISTER_RAW_SIZE (regno));
                      REGISTER_RAW_SIZE (regno));
}
}
 
 
/* Fetch all registers, or just one, from the child process.  */
/* Fetch all registers, or just one, from the child process.  */
 
 
void
void
fetch_inferior_registers (regno)
fetch_inferior_registers (regno)
     int regno;
     int regno;
{
{
  if (regno == -1 || regno == 0)
  if (regno == -1 || regno == 0)
    for (regno = 0; regno < NUM_REGS /*-NUM_FREGS*/ ; regno++)
    for (regno = 0; regno < NUM_REGS /*-NUM_FREGS*/ ; regno++)
      fetch_register (regno);
      fetch_register (regno);
  else
  else
    fetch_register (regno);
    fetch_register (regno);
}
}
 
 
/* Store our register values back into the inferior.
/* Store our register values back into the inferior.
   If REGNO is -1, do this for all registers.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */
   Otherwise, REGNO specifies which register (so we can save time).  */
 
 
void
void
store_inferior_registers (regno)
store_inferior_registers (regno)
     int regno;
     int regno;
{
{
  if (regno == -1)
  if (regno == -1)
    {
    {
      for (regno = 0; regno < NUM_REGS; regno++)
      for (regno = 0; regno < NUM_REGS; regno++)
        store_inferior_registers (regno);
        store_inferior_registers (regno);
    }
    }
  else
  else
    sim_store_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
    sim_store_register (gdbsim_desc, regno, &registers[REGISTER_BYTE (regno)],
                        REGISTER_RAW_SIZE (regno));
                        REGISTER_RAW_SIZE (regno));
}
}
 
 
/* Return nonzero if the given thread is still alive.  */
/* Return nonzero if the given thread is still alive.  */
int
int
mythread_alive (pid)
mythread_alive (pid)
     int pid;
     int pid;
{
{
  return 1;
  return 1;
}
}
 
 
/* Wait for process, returns status */
/* Wait for process, returns status */
 
 
unsigned char
unsigned char
mywait (status)
mywait (status)
     char *status;
     char *status;
{
{
  int sigrc;
  int sigrc;
  enum sim_stop reason;
  enum sim_stop reason;
 
 
  sim_stop_reason (gdbsim_desc, &reason, &sigrc);
  sim_stop_reason (gdbsim_desc, &reason, &sigrc);
  switch (reason)
  switch (reason)
    {
    {
    case sim_exited:
    case sim_exited:
      if (remote_debug)
      if (remote_debug)
        printf ("\nChild exited with retcode = %x \n", sigrc);
        printf ("\nChild exited with retcode = %x \n", sigrc);
      *status = 'W';
      *status = 'W';
      return sigrc;
      return sigrc;
 
 
#if 0
#if 0
    case sim_stopped:
    case sim_stopped:
      if (remote_debug)
      if (remote_debug)
        printf ("\nChild terminated with signal = %x \n", sigrc);
        printf ("\nChild terminated with signal = %x \n", sigrc);
      *status = 'X';
      *status = 'X';
      return sigrc;
      return sigrc;
#endif
#endif
 
 
    default:                    /* should this be sim_signalled or sim_stopped?  FIXME!! */
    default:                    /* should this be sim_signalled or sim_stopped?  FIXME!! */
      if (remote_debug)
      if (remote_debug)
        printf ("\nChild received signal = %x \n", sigrc);
        printf ("\nChild received signal = %x \n", sigrc);
      fetch_inferior_registers (0);
      fetch_inferior_registers (0);
      *status = 'T';
      *status = 'T';
      return (unsigned char) sigrc;
      return (unsigned char) sigrc;
    }
    }
}
}
 
 
/* Resume execution of the inferior process.
/* Resume execution of the inferior process.
   If STEP is nonzero, single-step it.
   If STEP is nonzero, single-step it.
   If SIGNAL is nonzero, give it that signal.  */
   If SIGNAL is nonzero, give it that signal.  */
 
 
void
void
myresume (step, signo)
myresume (step, signo)
     int step;
     int step;
     int signo;
     int signo;
{
{
  /* Should be using target_signal_to_host() or signal numbers in target.h
  /* Should be using target_signal_to_host() or signal numbers in target.h
     to convert GDB signal number to target signal number.  */
     to convert GDB signal number to target signal number.  */
  sim_resume (gdbsim_desc, step, signo);
  sim_resume (gdbsim_desc, step, signo);
}
}
 
 
/* Copy LEN bytes from inferior's memory starting at MEMADDR
/* Copy LEN bytes from inferior's memory starting at MEMADDR
   to debugger memory starting at MYADDR.  */
   to debugger memory starting at MYADDR.  */
 
 
void
void
read_inferior_memory (memaddr, myaddr, len)
read_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     char *myaddr;
     char *myaddr;
     int len;
     int len;
{
{
  sim_read (gdbsim_desc, memaddr, myaddr, len);
  sim_read (gdbsim_desc, memaddr, myaddr, len);
}
}
 
 
/* Copy LEN bytes of data from debugger memory at MYADDR
/* Copy LEN bytes of data from debugger memory at MYADDR
   to inferior's memory at MEMADDR.
   to inferior's memory at MEMADDR.
   On failure (cannot write the inferior)
   On failure (cannot write the inferior)
   returns the value of errno.  */
   returns the value of errno.  */
 
 
int
int
write_inferior_memory (memaddr, myaddr, len)
write_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     char *myaddr;
     char *myaddr;
     int len;
     int len;
{
{
  sim_write (gdbsim_desc, memaddr, myaddr, len);        /* should check for error.  FIXME!! */
  sim_write (gdbsim_desc, memaddr, myaddr, len);        /* should check for error.  FIXME!! */
  return 0;
  return 0;
}
}
 
 
void
void
initialize_low ()
initialize_low ()
{
{
}
}
 
 

powered by: WebSVN 2.1.0

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