Esempio n. 1
0
do_syscall ()
{

    /* We use this for simulated system calls; we may need to change
       it to a reserved instruction if we conflict with uses at
       Matsushita.  */
    int save_errno = errno;
    errno = 0;

    /* Registers passed to trap 0 */

    /* Function number.  */
#define FUNC   (State.regs[0])

    /* Parameters.  */
#define PARM1   (State.regs[1])
#define PARM2   (load_word (State.regs[REG_SP] + 12))
#define PARM3   (load_word (State.regs[REG_SP] + 16))

    /* Registers set by trap 0 */

#define RETVAL State.regs[0]	/* return value */
#define RETERR State.regs[1]	/* return error code */

    /* Turn a pointer in a register into a pointer into real memory. */
#define MEMPTR(x) (State.mem + x)

    if ( FUNC == TARGET_SYS_exit )
    {
        /* EXIT - caller can look in PARM1 to work out the reason */
        if (PARM1 == 0xdead)
            State.exception = SIGABRT;
        else
        {
            sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
                             sim_exited, PARM1);
            State.exception = SIGQUIT;
        }
        State.exited = 1;
    }
    else
    {
        CB_SYSCALL syscall;

        CB_SYSCALL_INIT (&syscall);
        syscall.arg1 = PARM1;
        syscall.arg2 = PARM2;
        syscall.arg3 = PARM3;
        syscall.func = FUNC;
        syscall.p1 = (PTR) simulator;
        syscall.read_mem = syscall_read_mem;
        syscall.write_mem = syscall_write_mem;
        cb_syscall (STATE_CALLBACK (simulator), &syscall);
        RETERR = syscall.errcode;
        RETVAL = syscall.result;
    }


    errno = save_errno;
}
Esempio n. 2
0
USI
m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

#ifdef SIM_HAVE_BREAKPOINTS
  /* Check for breakpoints "owned" by the simulator first, regardless
     of --environment.  */
  if (num == TRAP_BREAKPOINT)
    {
      /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
	 it doesn't return.  Otherwise it returns and let's us try.  */
      sim_handle_breakpoint (sd, current_cpu, pc);
      /* Fall through.  */
    }
#endif

  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
    {
      /* The new pc is the trap vector entry.
	 We assume there's a branch there to some handler.
         Use cr5 as EVB (EIT Vector Base) register.  */
      /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
      USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
      return new_pc;
    }

  switch (num)
    {
    case TRAP_SYSCALL :
      {
	CB_SYSCALL s;

	CB_SYSCALL_INIT (&s);
	s.func = m32rbf_h_gr_get (current_cpu, 0);
	s.arg1 = m32rbf_h_gr_get (current_cpu, 1);
	s.arg2 = m32rbf_h_gr_get (current_cpu, 2);
	s.arg3 = m32rbf_h_gr_get (current_cpu, 3);

	if (s.func == TARGET_SYS_exit)
	  {
	    sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
	  }

	s.p1 = (PTR) sd;
	s.p2 = (PTR) current_cpu;
	s.read_mem = syscall_read_mem;
	s.write_mem = syscall_write_mem;
	cb_syscall (cb, &s);
	m32rbf_h_gr_set (current_cpu, 2, s.errcode);
	m32rbf_h_gr_set (current_cpu, 0, s.result);
	m32rbf_h_gr_set (current_cpu, 1, s.result2);
	break;
      }

    case TRAP_BREAKPOINT:
      sim_engine_halt (sd, current_cpu, NULL, pc,
		       sim_stopped, SIM_SIGTRAP);
      break;

    case TRAP_FLUSH_CACHE:
      /* Do nothing.  */
      break;

    default :
      {
	/* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
        /* Use cr5 as EVB (EIT Vector Base) register.  */
        USI new_pc = m32rbf_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
	return new_pc;
      }
    }

  /* Fake an "rte" insn.  */
  /* FIXME: Should duplicate all of rte processing.  */
  return (pc & -4) + 4;
}
Esempio n. 3
0
void
bfin_syscall (SIM_CPU *cpu)
{
  SIM_DESC sd = CPU_STATE (cpu);
  const char * const *argv = (void *)STATE_PROG_ARGV (sd);
  host_callback *cb = STATE_CALLBACK (sd);
  bu32 args[6];
  CB_SYSCALL sc;
  char *p;
  char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
  int fmt_ret_hex = 0;

  CB_SYSCALL_INIT (&sc);

  if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    {
      /* Linux syscall.  */
      sc.func = PREG (0);
      sc.arg1 = args[0] = DREG (0);
      sc.arg2 = args[1] = DREG (1);
      sc.arg3 = args[2] = DREG (2);
      sc.arg4 = args[3] = DREG (3);
      /*sc.arg5 =*/ args[4] = DREG (4);
      /*sc.arg6 =*/ args[5] = DREG (5);
    }
  else
    {
      /* libgloss syscall.  */
      sc.func = PREG (0);
      sc.arg1 = args[0] = GET_LONG (DREG (0));
      sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
      sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
      sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
      /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
      /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
    }
  sc.p1 = (PTR) sd;
  sc.p2 = (PTR) cpu;
  sc.read_mem = sim_syscall_read_mem;
  sc.write_mem = sim_syscall_write_mem;

  /* Common cb_syscall() handles most functions.  */
  switch (cb_target_to_host_syscall (cb, sc.func))
    {
    case CB_SYS_exit:
      tbuf += sprintf (tbuf, "exit(%i)", args[0]);
      sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);

#ifdef CB_SYS_argc
    case CB_SYS_argc:
      tbuf += sprintf (tbuf, "argc()");
      sc.result = count_argc (argv);
      break;
    case CB_SYS_argnlen:
      {
      tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
	if (sc.arg1 < count_argc (argv))
	  sc.result = strlen (argv[sc.arg1]);
	else
	  sc.result = -1;
      }
      break;
    case CB_SYS_argn:
      {
	tbuf += sprintf (tbuf, "argn(%u)", args[0]);
	if (sc.arg1 < count_argc (argv))
	  {
	    const char *argn = argv[sc.arg1];
	    int len = strlen (argn);
	    int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
	    if (written == len + 1)
	      sc.result = sc.arg2;
	    else
	      sc.result = -1;
	  }
	else
	  sc.result = -1;
      }
      break;
#endif

    case CB_SYS_gettimeofday:
      {
	struct timeval _tv, *tv = &_tv;
	struct timezone _tz, *tz = &_tz;

	tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);

	if (sc.arg1 == 0)
	  tv = NULL;
	if (sc.arg2 == 0)
	  tz = NULL;
	sc.result = gettimeofday (tv, tz);

	if (sc.result == 0)
	  {
	    bu32 t;

	    if (tv)
	      {
		t = tv->tv_sec;
		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
		t = tv->tv_usec;
		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
	      }

	    if (sc.arg2)
	      {
		t = tz->tz_minuteswest;
		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
		t = tz->tz_dsttime;
		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
	      }
	  }
	else
	  goto sys_finish;
      }
      break;

    case CB_SYS_ioctl:
      /* XXX: hack just enough to get basic stdio w/uClibc ...  */
      tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
      if (sc.arg2 == 0x5401)
	{
	  sc.result = !isatty (sc.arg1);
	  sc.errcode = 0;
	}
      else
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      break;

    case CB_SYS_mmap2:
      {
	static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;

	fmt_ret_hex = 1;
	tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
			 args[0], args[1], args[2], args[3], args[4], args[5]);

	sc.errcode = 0;

	if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
	  /* XXX: We don't handle zeroing, but default is all zeros.  */;
	else if (args[4] >= MAX_CALLBACK_FDS)
	  sc.errcode = TARGET_ENOSYS;
	else
	  {
#ifdef HAVE_PREAD
	    char *data = xmalloc (sc.arg2);

	    /* XXX: Should add a cb->pread.  */
	    if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
	      sc.write_mem (cb, &sc, heap, data, sc.arg2);
	    else
	      sc.errcode = TARGET_EINVAL;

	    free (data);
#else
	    sc.errcode = TARGET_ENOSYS;
#endif
	  }

	if (sc.errcode)
	  {
	    sc.result = -1;
	    break;
	  }

	sc.result = heap;
	heap += sc.arg2;
	/* Keep it page aligned.  */
	heap = ALIGN (heap, 4096);

	break;
      }

    case CB_SYS_munmap:
      /* XXX: meh, just lie for mmap().  */
      tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
      sc.result = 0;
      break;

    case CB_SYS_dup2:
      tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
      if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
	  goto sys_finish;
	}
      break;

    case CB_SYS__llseek:
      tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
		       args[0], args[1], args[2], args[3], args[4]);
      sc.func = TARGET_LINUX_SYS_lseek;
      if (sc.arg2)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.arg2 = sc.arg3;
	  sc.arg3 = args[4];
	  cb_syscall (cb, &sc);
	  if (sc.result != -1)
	    {
	      bu32 z = 0;
	      sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
	      sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
	    }
	}
      break;

    /* XXX: Should add a cb->pread.  */
    case CB_SYS_pread:
      tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
		       args[0], args[1], args[2], args[3]);
      if (sc.arg1 >= MAX_CALLBACK_FDS)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  long old_pos, read_result, read_errcode;

	  /* Get current filepos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = 0;
	  sc.arg3 = SEEK_CUR;
	  cb_syscall (cb, &sc);
	  if (sc.result == -1)
	    break;
	  old_pos = sc.result;

	  /* Move to the new pos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = args[3];
	  sc.arg3 = SEEK_SET;
	  cb_syscall (cb, &sc);
	  if (sc.result == -1)
	    break;

	  /* Read the data.  */
	  sc.func = TARGET_LINUX_SYS_read;
	  sc.arg2 = args[1];
	  sc.arg3 = args[2];
	  cb_syscall (cb, &sc);
	  read_result = sc.result;
	  read_errcode = sc.errcode;

	  /* Move back to the old pos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = old_pos;
	  sc.arg3 = SEEK_SET;
	  cb_syscall (cb, &sc);

	  sc.result = read_result;
	  sc.errcode = read_errcode;
	}
      break;

    case CB_SYS_getcwd:
      tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);

      p = alloca (sc.arg2);
      if (getcwd (p, sc.arg2) == NULL)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
	  sc.result = sc.arg1;
	}
      break;

    case CB_SYS_stat64:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_stat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;
    case CB_SYS_lstat64:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_lstat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;
    case CB_SYS_fstat64:
      tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_fstat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;

    case CB_SYS_ftruncate64:
      tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
      sc.func = TARGET_LINUX_SYS_ftruncate;
      cb_syscall (cb, &sc);
      break;

    case CB_SYS_getuid:
    case CB_SYS_getuid32:
      tbuf += sprintf (tbuf, "getuid()");
      sc.result = getuid ();
      goto sys_finish;
    case CB_SYS_getgid:
    case CB_SYS_getgid32:
      tbuf += sprintf (tbuf, "getgid()");
      sc.result = getgid ();
      goto sys_finish;
    case CB_SYS_setuid:
      sc.arg1 &= 0xffff;
    case CB_SYS_setuid32:
      tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
      sc.result = setuid (sc.arg1);
      goto sys_finish;
    case CB_SYS_setgid:
      sc.arg1 &= 0xffff;
    case CB_SYS_setgid32:
      tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
      sc.result = setgid (sc.arg1);
      goto sys_finish;

    case CB_SYS_getpid:
      tbuf += sprintf (tbuf, "getpid()");
      sc.result = getpid ();
      goto sys_finish;
    case CB_SYS_kill:
      tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
      /* Only let the app kill itself.  */
      if (sc.arg1 != getpid ())
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EPERM;
	}
      else
	{
#ifdef HAVE_KILL
	  sc.result = kill (sc.arg1, sc.arg2);
	  goto sys_finish;
#else
	  sc.result = -1;
	  sc.errcode = TARGET_ENOSYS;
#endif
	}
      break;

    case CB_SYS_open:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
		       args[0], tstr, args[1], args[2]);
      goto case_default;
    case CB_SYS_close:
      tbuf += sprintf (tbuf, "close(%i)", args[0]);
      goto case_default;
    case CB_SYS_read:
      tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
      goto case_default;
    case CB_SYS_write:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
		       args[0], args[1], tstr, args[2]);
      goto case_default;
    case CB_SYS_lseek:
      tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
      goto case_default;
    case CB_SYS_unlink:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
      goto case_default;
    case CB_SYS_truncate:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_ftruncate:
      tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
      goto case_default;
    case CB_SYS_rename:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
      goto case_default;
    case CB_SYS_stat:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_fstat:
      tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
      goto case_default;
    case CB_SYS_lstat:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_pipe:
      tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
      goto case_default;

    default:
      tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
		       args[0], args[1], args[2], args[3], args[4], args[5]);
    case_default:
      cb_syscall (cb, &sc);
      break;

    sys_finish:
      if (sc.result == -1)
	{
	  cb->last_errno = errno;
	  sc.errcode = cb->get_errno (cb);
	}
    }

  TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
		sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
		sc.result, sc.errcode);

  tbuf += sprintf (tbuf, " = ");
  if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    {
      if (sc.result == -1)
	{
	  tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
	  if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
	    {
	      sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
			      PCREG, sc.func);
	    }
	  SET_DREG (0, -sc.errcode);
	}
      else
	{
	  if (fmt_ret_hex)
	    tbuf += sprintf (tbuf, "%#lx", sc.result);
	  else
	    tbuf += sprintf (tbuf, "%lu", sc.result);
	  SET_DREG (0, sc.result);
	}
    }
  else
    {
      tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
      SET_DREG (0, sc.result);
      SET_DREG (1, sc.result2);
      SET_DREG (2, sc.errcode);
    }

  TRACE_SYSCALL (cpu, "%s", _tbuf);
}
Esempio n. 4
0
/* Handle TRA and TIRA insns.  */
void
frv_itrap (SIM_CPU *current_cpu, PCADDR pc, USI base, SI offset)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);
  USI num = ((base + offset) & 0x7f) + 0x80;

#ifdef SIM_HAVE_BREAKPOINTS
  /* Check for breakpoints "owned" by the simulator first, regardless
     of --environment.  */
  if (num == TRAP_BREAKPOINT)
    {
      /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
	 it doesn't return.  Otherwise it returns and let's us try.  */
      sim_handle_breakpoint (sd, current_cpu, pc);
      /* Fall through.  */
    }
#endif

  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
    {
      frv_queue_software_interrupt (current_cpu, num);
      return;
    }

  switch (num)
    {
    case TRAP_SYSCALL :
      {
	CB_SYSCALL s;
	CB_SYSCALL_INIT (&s);
	s.func = GET_H_GR (7);
	s.arg1 = GET_H_GR (8);
	s.arg2 = GET_H_GR (9);
	s.arg3 = GET_H_GR (10);

	if (s.func == TARGET_SYS_exit)
	  {
	    sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
	  }

	s.p1 = (PTR) sd;
	s.p2 = (PTR) current_cpu;
	s.read_mem = syscall_read_mem;
	s.write_mem = syscall_write_mem;
	cb_syscall (cb, &s);
	SET_H_GR (8, s.result);
	SET_H_GR (9, s.result2);
	SET_H_GR (10, s.errcode);
	break;
      }

    case TRAP_BREAKPOINT:
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
      break;

      /* Add support for dumping registers, either at fixed traps, or all
	 unknown traps if configured with --enable-sim-trapdump.  */
    default:
#if !TRAPDUMP
      frv_queue_software_interrupt (current_cpu, num);
      return;
#endif

#ifdef TRAP_REGDUMP1
    case TRAP_REGDUMP1:
#endif

#ifdef TRAP_REGDUMP2
    case TRAP_REGDUMP2:
#endif

#if TRAPDUMP || (defined (TRAP_REGDUMP1)) || (defined (TRAP_REGDUMP2))
      {
	char buf[256];
	int i, j;

	buf[0] = 0;
	if (STATE_TEXT_SECTION (sd)
	    && pc >= STATE_TEXT_START (sd)
	    && pc < STATE_TEXT_END (sd))
	  {
	    const char *pc_filename = (const char *)0;
	    const char *pc_function = (const char *)0;
	    unsigned int pc_linenum = 0;

	    if (bfd_find_nearest_line (STATE_PROG_BFD (sd),
				       STATE_TEXT_SECTION (sd),
				       (struct bfd_symbol **) 0,
				       pc - STATE_TEXT_START (sd),
				       &pc_filename, &pc_function, &pc_linenum)
		&& (pc_function || pc_filename))
	      {
		char *p = buf+2;
		buf[0] = ' ';
		buf[1] = '(';
		if (pc_function)
		  {
		    strcpy (p, pc_function);
		    p += strlen (p);
		  }
		else
		  {
		    char *q = (char *) strrchr (pc_filename, '/');
		    strcpy (p, (q) ? q+1 : pc_filename);
		    p += strlen (p);
		  }

		if (pc_linenum)
		  {
		    sprintf (p, " line %d", pc_linenum);
		    p += strlen (p);
		  }

		p[0] = ')';
		p[1] = '\0';
		if ((p+1) - buf > sizeof (buf))
		  abort ();
	      }
	  }

	sim_io_printf (sd,
		       "\nRegister dump,    pc = 0x%.8x%s, base = %u, offset = %d\n",
		       (unsigned)pc, buf, (unsigned)base, (int)offset);

	for (i = 0; i < 64; i += 8)
	  {
	    long g0 = (long)GET_H_GR (i);
	    long g1 = (long)GET_H_GR (i+1);
	    long g2 = (long)GET_H_GR (i+2);
	    long g3 = (long)GET_H_GR (i+3);
	    long g4 = (long)GET_H_GR (i+4);
	    long g5 = (long)GET_H_GR (i+5);
	    long g6 = (long)GET_H_GR (i+6);
	    long g7 = (long)GET_H_GR (i+7);

	    if ((g0 | g1 | g2 | g3 | g4 | g5 | g6 | g7) != 0)
	      sim_io_printf (sd,
			     "\tgr%02d - gr%02d:   0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
			     i, i+7, g0, g1, g2, g3, g4, g5, g6, g7);
	  }

	for (i = 0; i < 64; i += 8)
	  {
	    long f0 = (long)GET_H_FR (i);
	    long f1 = (long)GET_H_FR (i+1);
	    long f2 = (long)GET_H_FR (i+2);
	    long f3 = (long)GET_H_FR (i+3);
	    long f4 = (long)GET_H_FR (i+4);
	    long f5 = (long)GET_H_FR (i+5);
	    long f6 = (long)GET_H_FR (i+6);
	    long f7 = (long)GET_H_FR (i+7);

	    if ((f0 | f1 | f2 | f3 | f4 | f5 | f6 | f7) != 0)
	      sim_io_printf (sd,
			     "\tfr%02d - fr%02d:   0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
			     i, i+7, f0, f1, f2, f3, f4, f5, f6, f7);
	  }

	sim_io_printf (sd,
		       "\tlr/lcr/cc/ccc: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
		       (long)GET_H_SPR (272),
		       (long)GET_H_SPR (273),
		       (long)GET_H_SPR (256),
		       (long)GET_H_SPR (263));
      }
      break;
#endif
    }
}
Esempio n. 5
0
USI
fr30_int (SIM_CPU *current_cpu, PCADDR pc, int num)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

#ifdef SIM_HAVE_BREAKPOINTS
  /* Check for breakpoints "owned" by the simulator first, regardless
     of --environment.  */
  if (num == TRAP_BREAKPOINT)
    {
      /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
	 it doesn't return.  Otherwise it returns and let's us try.  */
      sim_handle_breakpoint (sd, current_cpu, pc);
      /* Fall through.  */
    }
#endif

  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
    {
      /* The new pc is the trap vector entry.
	 We assume there's a branch there to some handler.  */
      USI new_pc;
      setup_int (current_cpu, pc);
      fr30bf_h_ibit_set (current_cpu, 0);
      new_pc = GETMEMSI (current_cpu, pc,
			 fr30bf_h_dr_get (current_cpu, H_DR_TBR)
			 + 1024 - ((num + 1) * 4));
      return new_pc;
    }

  switch (num)
    {
    case TRAP_SYSCALL :
      {
	/* TODO: find out what the ABI for this is */
	CB_SYSCALL s;

	CB_SYSCALL_INIT (&s);
	s.func = fr30bf_h_gr_get (current_cpu, 0);
	s.arg1 = fr30bf_h_gr_get (current_cpu, 4);
	s.arg2 = fr30bf_h_gr_get (current_cpu, 5);
	s.arg3 = fr30bf_h_gr_get (current_cpu, 6);

	if (s.func == TARGET_SYS_exit)
	  {
	    sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
	  }

	s.p1 = (PTR) sd;
	s.p2 = (PTR) current_cpu;
	s.read_mem = syscall_read_mem;
	s.write_mem = syscall_write_mem;
	cb_syscall (cb, &s);
	fr30bf_h_gr_set (current_cpu, 2, s.errcode); /* TODO: check this one */
	fr30bf_h_gr_set (current_cpu, 4, s.result);
	fr30bf_h_gr_set (current_cpu, 1, s.result2); /* TODO: check this one */
	break;
      }

    case TRAP_BREAKPOINT:
      sim_engine_halt (sd, current_cpu, NULL, pc,
		       sim_stopped, SIM_SIGTRAP);
      break;

    default :
      {
	USI new_pc;
	setup_int (current_cpu, pc);
	fr30bf_h_ibit_set (current_cpu, 0);
	new_pc = GETMEMSI (current_cpu, pc,
			   fr30bf_h_dr_get (current_cpu, H_DR_TBR)
			   + 1024 - ((num + 1) * 4));
	return new_pc;
      }
    }

  /* Fake an "reti" insn.
     Since we didn't push anything to stack, all we need to do is
     update pc.  */
  return pc + 2;
}