/* gdb-if.c -- sim interface to GDB.
-Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+Copyright (C) 2008-2019 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
This file is part of the GNU simulators.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include "config.h"
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#include "load.h"
#include "syscalls.h"
#include "err.h"
+#include "trace.h"
/* Ideally, we'd wrap up all the minisim's data structures in an
object and pass that around. However, neither GDB nor run needs
"This is the sole rx minisim instance. See libsim.a's global variables."
};
-static int open;
+static int rx_sim_is_open;
SIM_DESC
sim_open (SIM_OPEN_KIND kind,
struct host_callback_struct *callback,
- struct bfd *abfd, char **argv)
+ struct bfd *abfd, char * const *argv)
{
- if (open)
+ if (rx_sim_is_open)
fprintf (stderr, "rx minisim: re-opened sim\n");
/* The 'run' interface doesn't use this function, so we don't care
execution_error_init_debugger ();
sim_disasm_init (abfd);
- open = 1;
+ rx_sim_is_open = 1;
return &the_minisim;
}
/* Not much to do. At least free up our memory. */
init_mem ();
- open = 0;
+ rx_sim_is_open = 0;
}
static bfd *
struct swap_list *sl;
bfd_size_type size;
- size = bfd_get_section_size (s);
+ size = bfd_section_size (s);
if (size <= 0)
continue;
sl = malloc (sizeof (struct swap_list));
assert (sl != NULL);
sl->next = swap_list;
- sl->start = bfd_section_lma (abfd, s);
+ sl->start = bfd_section_lma (s);
sl->end = sl->start + size;
swap_list = sl;
}
}
SIM_RC
-sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
+sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty)
{
check_desc (sd);
if (!abfd)
return SIM_RC_FAIL;
- rx_load (abfd);
+ rx_load (abfd, get_callbacks ());
build_swap_list (abfd);
return SIM_RC_OK;
}
SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char * const *argv, char * const *env)
{
check_desc (sd);
if (abfd)
{
- rx_load (abfd);
+ rx_load (abfd, NULL);
build_swap_list (abfd);
}
}
int
-sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
+sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
{
int i;
case sim_rx_fpsw_regnum:
size = sizeof (regs.r_fpsw);
break;
+ case sim_rx_acc_regnum:
+ size = sizeof (regs.r_acc);
+ break;
default:
size = 0;
break;
case sim_rx_fpsw_regnum:
val = get_reg (fpsw);
break;
+ case sim_rx_acc_regnum:
+ val = ((DI) get_reg (acchi) << 32) | get_reg (acclo);
+ break;
default:
fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
regno);
check_desc (sd);
if (!check_regno (regno))
- return 0;
+ return -1;
size = reg_size (regno);
if (length != size)
- return 0;
+ return -1;
if (rx_big_endian)
val = get_be (buf, length);
case sim_rx_fpsw_regnum:
put_reg (fpsw, val);
break;
+ case sim_rx_acc_regnum:
+ put_reg (acclo, val & 0xffffffff);
+ put_reg (acchi, (val >> 32) & 0xffffffff);
+ break;
default:
fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
regno);
- return -1;
+ return 0;
}
return size;
/* Given a signal number used by the RX bsp (that is, newlib),
- return a host signal number. (Oddly, the gdb/sim interface uses
- host signal numbers...) */
-int
-rx_signal_to_host (int rx)
+ return a target signal number used by GDB. */
+static int
+rx_signal_to_gdb_signal (int rx)
{
switch (rx)
{
case 4:
-#ifdef SIGILL
- return SIGILL;
-#else
- return SIGSEGV;
-#endif
+ return GDB_SIGNAL_ILL;
case 5:
- return SIGTRAP;
+ return GDB_SIGNAL_TRAP;
case 10:
-#ifdef SIGBUS
- return SIGBUS;
-#else
- return SIGSEGV;
-#endif
+ return GDB_SIGNAL_BUS;
case 11:
- return SIGSEGV;
+ return GDB_SIGNAL_SEGV;
case 24:
-#ifdef SIGXCPU
- return SIGXCPU;
-#else
- break;
-#endif
+ return GDB_SIGNAL_XCPU;
case 2:
- return SIGINT;
+ return GDB_SIGNAL_INT;
case 8:
-#ifdef SIGFPE
- return SIGFPE;
-#else
- break;
-#endif
+ return GDB_SIGNAL_FPE;
case 6:
- return SIGABRT;
+ return GDB_SIGNAL_ABRT;
}
return 0;
if (execution_error_get_last_error () != SIM_ERR_NONE)
{
reason = sim_stopped;
- siggnal = TARGET_SIGNAL_SEGV;
+ siggnal = GDB_SIGNAL_SEGV;
}
if (RX_STEPPED (rc) || RX_HIT_BREAK (rc))
{
reason = sim_stopped;
- siggnal = TARGET_SIGNAL_TRAP;
+ siggnal = GDB_SIGNAL_TRAP;
}
else if (RX_STOPPED (rc))
{
reason = sim_stopped;
- siggnal = rx_signal_to_host (RX_STOP_SIG (rc));
+ siggnal = rx_signal_to_gdb_signal (RX_STOP_SIG (rc));
}
else
{
void
sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
{
+ int rc;
+
check_desc (sd);
if (sig_to_deliver != 0)
execution_error_clear_last_error ();
if (step)
- handle_step (decode_opcode ());
+ {
+ rc = setjmp (decode_jmp_buf);
+ if (rc == 0)
+ rc = decode_opcode ();
+ handle_step (rc);
+ }
else
{
/* We don't clear 'stop' here, because then we would miss
{
stop = 0;
reason = sim_stopped;
- siggnal = TARGET_SIGNAL_INT;
+ siggnal = GDB_SIGNAL_INT;
break;
}
- int rc = decode_opcode ();
+ rc = setjmp (decode_jmp_buf);
+ if (rc == 0)
+ rc = decode_opcode ();
if (execution_error_get_last_error () != SIM_ERR_NONE)
{
reason = sim_stopped;
- siggnal = TARGET_SIGNAL_SEGV;
+ siggnal = GDB_SIGNAL_SEGV;
break;
}
}
void
-sim_do_command (SIM_DESC sd, char *cmd)
+sim_do_command (SIM_DESC sd, const char *cmd)
{
- check_desc (sd);
+ const char *args;
+ char *p = strdup (cmd);
- char *p = cmd;
+ check_desc (sd);
/* Skip leading whitespace. */
while (isspace (*p))
/* Null-terminate the command word, and record the start of any
further arguments. */
- char *args;
if (*p)
{
*p = '\0';
{
if (strcmp (args, "on") == 0)
verbose = 1;
+ else if (strcmp (args, "noisy") == 0)
+ verbose = 2;
else if (strcmp (args, "off") == 0)
verbose = 0;
else
- printf ("The 'sim verbose' command expects 'on' or 'off'"
+ printf ("The 'sim verbose' command expects 'on', 'noisy', or 'off'"
" as an argument.\n");
}
else
printf ("The 'sim' command expects either 'trace' or 'verbose'"
" as a subcommand.\n");
+
+ free (p);
+}
+
+char **
+sim_complete_command (SIM_DESC sd, const char *text, const char *word)
+{
+ return NULL;
}