aboutsummaryrefslogtreecommitdiff
path: root/gdb/monitor.c
diff options
context:
space:
mode:
authorMark Alexander <marka@cygnus>1997-12-29 21:50:10 +0000
committerMark Alexander <marka@cygnus>1997-12-29 21:50:10 +0000
commit7e9576e098e8f293a9bc9d53da7cda4335aa7d0f (patch)
tree42cf65efd96da2a48dde35adda62df5dac283d56 /gdb/monitor.c
parent76ef4165507354d59b8f374404f735b97b09f79f (diff)
downloadgdb-7e9576e098e8f293a9bc9d53da7cda4335aa7d0f.zip
gdb-7e9576e098e8f293a9bc9d53da7cda4335aa7d0f.tar.gz
gdb-7e9576e098e8f293a9bc9d53da7cda4335aa7d0f.tar.bz2
* dve3900-rom.c: New file to support Densan DVE-R3900/20 board.
* monitor.c (monitor_debug): Move to utils.c, rename to puts_debug. (monitor_write_memory, monitor_read_memory, monitor_insert_breakpoint, monitor_remove_breakpoint): Remove useless address bits if current monitor has MO_ADDR_BITS_REMOVE flag. * monitor.h (MO_ADDR_BITS_REMOVE): Define. * utils.c (puts_debug): Formerly monitor_debug from monitor.c; move here and make public. Add better support for carriage returns. * defs.h (puts_debug): Declare. * dsrec.c (load_srec): Use puts_debug to print remotedebug information. Output header record correctly. (make_srec): Output a header record instead of a termination record if sect is non-NULL (value is ignored), but abfd is NULL. * config/mips/tm-tx39.h (DEFAULT_MIPS_TYPE): Remove definition. (REGISTER_NAMES): Define to add R3900-specific registers. * config/mips/tm-tx39l.h: Ditto. * config/mips/tx39.mt (TDEPFILES): Add dve3900-rom.o and support files. * config/mips/tx39l.mt: Ditto.
Diffstat (limited to 'gdb/monitor.c')
-rw-r--r--gdb/monitor.c247
1 files changed, 152 insertions, 95 deletions
diff --git a/gdb/monitor.c b/gdb/monitor.c
index b7a56aa..97f5a50 100644
--- a/gdb/monitor.c
+++ b/gdb/monitor.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for boot monitors, for GDB.
- Copyright 1990, 1991, 1992, 1993, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1995, 1996, 1997
Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
Resurrected from the ashes by Stu Grossman.
@@ -88,15 +88,17 @@ static void monitor_kill PARAMS ((void));
static void monitor_load PARAMS ((char *file, int from_tty));
static void monitor_mourn_inferior PARAMS ((void));
static void monitor_stop PARAMS ((void));
-static void monitor_debug PARAMS ((char *prefix, char *string, char *suffix));
static int monitor_read_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
static int monitor_write_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
static int monitor_expect_regexp PARAMS ((struct re_pattern_buffer *pat,
char *buf, int buflen));
+#if 0
static int from_hex PARAMS ((int a));
static unsigned long get_hex_word PARAMS ((void));
+#endif
+static void parse_register_dump PARAMS ((char *, int));
static struct monitor_ops *current_monitor;
@@ -129,68 +131,18 @@ static DCACHE *remote_dcache;
static int first_time=0; /* is this the first time we're executing after
gaving created the child proccess? */
-/* monitor_debug is like fputs_unfiltered, except it prints special
- characters in printable fashion. */
+/* Convert hex digit A to a number. */
-static void
-monitor_debug (prefix, string, suffix)
- char *prefix;
- char *string;
- char *suffix;
+static int
+fromhex (a)
+ int a;
{
- int ch;
-
- /* print prefix and suffix after each line */
- static int new_line=1;
- static char *prev_prefix = "";
- static char *prev_suffix = "";
-
- /* if the prefix is changing, print the previous suffix, a new line,
- and the new prefix */
- if (strcmp(prev_prefix, prefix) != 0 && !new_line)
- {
- fputs_unfiltered (prev_suffix, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- fputs_unfiltered (prefix, gdb_stderr);
- }
- prev_prefix = prefix;
- prev_suffix = suffix;
-
- /* print prefix if last char was a newline*/
-
- if (new_line == 1) {
- fputs_unfiltered (prefix, gdb_stderr);
- new_line=0;
- }
- if (strchr(string,'\n')) /* save state for next call */
- new_line=1;
-
- while ((ch = *string++) != '\0')
- {
- switch (ch) {
- default:
- if (isprint (ch))
- fputc_unfiltered (ch, gdb_stderr);
-
- else
- fprintf_unfiltered (gdb_stderr, "\\%03o", ch);
-
- break;
-
- case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break;
- case '\b': fputs_unfiltered ("\\b", gdb_stderr); break;
- case '\f': fputs_unfiltered ("\\f", gdb_stderr); break;
- case '\n': fputs_unfiltered ("\\n", gdb_stderr); break;
- case '\r': fputs_unfiltered ("\\r", gdb_stderr); break;
- case '\t': fputs_unfiltered ("\\t", gdb_stderr); break;
- case '\v': fputs_unfiltered ("\\v", gdb_stderr); break;
- }
- }
-
- if (new_line==1) { /* print suffix if last char was a newline */
- fputs_unfiltered (suffix, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- }
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ error ("Invalid hex digit %d", a);
}
/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo.
@@ -219,7 +171,7 @@ monitor_printf_noecho (va_alist)
vsprintf (sndbuf, pattern, args);
if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ puts_debug ("sent -->", sndbuf, "<--");
len = strlen (sndbuf);
@@ -256,7 +208,7 @@ monitor_printf (va_alist)
vsprintf (sndbuf, pattern, args);
if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ puts_debug ("sent -->", sndbuf, "<--");
len = strlen (sndbuf);
@@ -297,7 +249,7 @@ readchar (timeout)
char buf[2];
buf[0] = c;
buf[1] = '\0';
- monitor_debug ("read -->", buf, "<--");
+ puts_debug ("read -->", buf, "<--");
}
}
@@ -478,6 +430,7 @@ monitor_expect_prompt (buf, buflen)
/* Get N 32-bit words from remote, each preceded by a space, and put
them in registers starting at REGNO. */
+#if 0
static unsigned long
get_hex_word ()
{
@@ -501,6 +454,7 @@ get_hex_word ()
return val;
}
+#endif
static void
compile_pattern (pattern, compiled_pattern, fastmap)
@@ -536,7 +490,6 @@ monitor_open (args, mon_ops, from_tty)
int from_tty;
{
char *name;
- int i;
char **p;
if (mon_ops->magic != MONITOR_OPS_MAGIC)
@@ -725,7 +678,7 @@ monitor_resume (pid, step, sig)
form REG=VAL. Each description is split up into a name and a value
string which are passed down to monitor specific code. */
-static char *
+static void
parse_register_dump (buf, len)
char *buf;
int len;
@@ -899,7 +852,13 @@ monitor_fetch_register (regno)
searching from the start of the buf. */
if (current_monitor->getreg.resp_delim)
- monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ {
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ /* Handle case of first 32 registers listed in pairs. */
+ if (current_monitor->flags & MO_32_REGS_PAIRED
+ && regno & 1 == 1 && regno < 32)
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ }
/* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
if (current_monitor->flags & MO_HEX_PREFIX)
@@ -957,7 +916,8 @@ monitor_fetch_register (regno)
/* Read the remote registers into the block regs. */
-static void monitor_dump_regs ()
+static void
+monitor_dump_regs ()
{
char buf[1024];
int resp_len;
@@ -1007,19 +967,26 @@ monitor_store_register (regno)
val = read_register (regno);
- /* send the register deposit command */
+ /* send the register deposit command */
if (current_monitor->flags & MO_REGISTER_VALUE_FIRST)
monitor_printf (current_monitor->setreg.cmd, val, name);
+ else if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf (current_monitor->setreg.cmd, name);
else
monitor_printf (current_monitor->setreg.cmd, name, val);
-/* It's possible that there are actually some monitors out there that
- will prompt you when you set a register. In that case, you may
- need to add some code here to deal with TERM and TERM_CMD (see
- monitor_fetch_register to get an idea of what's needed...) */
+ if (current_monitor->setreg.term)
+ {
+ monitor_expect (current_monitor->setreg.term, NULL, 0);
- monitor_expect_prompt (NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%x\r", val);
+
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ monitor_expect_prompt (NULL, 0);
}
/* Store the remote registers. */
@@ -1067,6 +1034,9 @@ monitor_write_memory (memaddr, myaddr, len)
char *cmd;
int i;
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
/* Use memory fill command for leading 0 bytes. */
if (current_monitor->fill)
@@ -1117,6 +1087,19 @@ monitor_write_memory (memaddr, myaddr, len)
if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
monitor_printf_noecho (cmd, memaddr, val);
+ else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
+ {
+
+ monitor_printf_noecho (cmd, memaddr);
+
+ if (current_monitor->setmem.term)
+ {
+ monitor_expect (current_monitor->setmem.term, NULL, 0);
+
+ monitor_printf ("%x\r", val);
+
+ }
+ }
else
monitor_printf (cmd, memaddr, val);
@@ -1247,9 +1230,9 @@ monitor_read_memory_single (memaddr, myaddr, len)
return len;
}
-/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory
- at MEMADDR. Returns length moved. Currently, we only do one byte at a
- time. */
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+ memory at MEMADDR. Returns length moved. Currently, we do no more
+ than 16 bytes at a time. */
static int
monitor_read_memory (memaddr, myaddr, len)
@@ -1258,18 +1241,22 @@ monitor_read_memory (memaddr, myaddr, len)
int len;
{
unsigned int val;
- unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
char buf[512];
char *p, *p1;
- char *name;
int resp_len;
int i;
+ CORE_ADDR dumpaddr;
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
return monitor_read_memory_single (memaddr, myaddr, len);
len = min (len, 16);
+ dumpaddr = memaddr & ~0xf;
+
/* See if xfer would cross a 16 byte boundary. If so, clip it. */
if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0)
len = ((memaddr + len) & ~0xf) - memaddr;
@@ -1278,6 +1265,8 @@ monitor_read_memory (memaddr, myaddr, len)
if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE)
monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len - 1);
+ else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ monitor_printf (current_monitor->getmem.cmdb, dumpaddr);
else
monitor_printf (current_monitor->getmem.cmdb, memaddr, len);
@@ -1333,6 +1322,27 @@ monitor_read_memory (memaddr, myaddr, len)
#endif
}
+ if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ {
+ i = len;
+ while (!(*p == '\000' || *p == '\n' || *p == '\r') && i > 0)
+ {
+ if (isxdigit (*p))
+ {
+ if (dumpaddr >= memaddr && i > 0)
+ {
+ val = fromhex (*p) * 16 + fromhex (*(p+1));
+ *myaddr++ = val;
+ --i;
+ }
+ ++dumpaddr;
+ ++p;
+ }
+ ++p;
+ }
+ return len;
+ }
+
for (i = len; i > 0; i--)
{
/* Skip non-hex chars, but bomb on end of string and newlines */
@@ -1341,6 +1351,7 @@ monitor_read_memory (memaddr, myaddr, len)
{
if (isxdigit (*p))
break;
+
if (*p == '\000' || *p == '\n' || *p == '\r')
error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s", memaddr, resp_len, buf);
p++;
@@ -1421,20 +1432,24 @@ monitor_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
- /* This is only used to compute the size of a breakpoint. */
-#ifdef BREAKPOINT
- static unsigned char break_insn[] = BREAKPOINT;
-#else
- /* In the bi-endian case we assume breakpoints are the same size. */
- static unsigned char break_insn[] = BIG_BREAKPOINT;
-#endif
+ unsigned char *bp;
+ int bplen;
+
+ if (current_monitor->set_break == NULL)
+ error ("No set_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
+ /* Determine appropriate breakpoint size for this address. */
+ bp = memory_breakpoint_from_pc (&addr, &bplen);
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == 0)
{
breakaddr[i] = addr;
- monitor_read_memory (addr, shadow, sizeof (break_insn));
+ monitor_read_memory (addr, shadow, bplen);
monitor_printf (current_monitor->set_break, addr);
monitor_expect_prompt (NULL, 0);
return 0;
@@ -1453,14 +1468,22 @@ monitor_remove_breakpoint (addr, shadow)
{
int i;
+ if (current_monitor->clr_break == NULL)
+ error ("No clr_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == addr)
{
breakaddr[i] = 0;
/* some monitors remove breakpoints based on the address */
- if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
+ if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
monitor_printf (current_monitor->clr_break, addr);
+ else if (current_monitor->flags & MO_CLR_BREAK_1_BASED)
+ monitor_printf (current_monitor->clr_break, i + 1);
else
monitor_printf (current_monitor->clr_break, i);
monitor_expect_prompt (NULL, 0);
@@ -1477,10 +1500,25 @@ monitor_remove_breakpoint (addr, shadow)
static int
monitor_wait_srec_ack ()
{
- /* FIXME: eventually we'll want to be able to handle acknowledgements
- of something other than a '+' character. Right now this is only
- going to work for EST visionICE. */
- return readchar (timeout) == '+';
+ int i, ch;
+
+ if (current_monitor->flags & MO_SREC_ACK_PLUS)
+ {
+ return (readchar (timeout) == '+');
+ }
+ else if (current_monitor->flags & MO_SREC_ACK_ROTATE)
+ {
+ /* Eat two backspaces, a "rotating" char (|/-\), and a space. */
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ }
+ return 1;
}
/* monitor_load -- download a file. */
@@ -1496,12 +1534,23 @@ monitor_load (file, from_tty)
current_monitor->load_routine (monitor_desc, file, hashmark);
else
{ /* The default is ascii S-records */
+ int n;
+ unsigned long load_offset;
+ char buf[128];
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf (file, "%s 0x%lx", buf, &load_offset);
+ if (n > 1)
+ file = buf;
+ else
+ load_offset = 0;
+
monitor_printf (current_monitor->load);
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
-/* FIXME Should add arg here for load_offset (already done for generic_load) */
- load_srec (monitor_desc, file, 32, SREC_ALL, hashmark,
+ load_srec (monitor_desc, file, (bfd_vma) load_offset,
+ 32, SREC_ALL, hashmark,
current_monitor->flags & MO_SREC_ACK ?
monitor_wait_srec_ack : NULL);
@@ -1563,6 +1612,7 @@ monitor_command (args, from_tty)
/* Convert hex digit A to a number. */
+#if 0
static int
from_hex (a)
int a;
@@ -1576,6 +1626,13 @@ from_hex (a)
error ("Reply contains invalid hex digit 0x%x", a);
}
+#endif
+
+char *
+monitor_get_dev_name ()
+{
+ return dev_name;
+}
static struct target_ops monitor_ops =
{