diff options
author | Mark Alexander <marka@cygnus> | 1997-12-29 21:50:10 +0000 |
---|---|---|
committer | Mark Alexander <marka@cygnus> | 1997-12-29 21:50:10 +0000 |
commit | 7e9576e098e8f293a9bc9d53da7cda4335aa7d0f (patch) | |
tree | 42cf65efd96da2a48dde35adda62df5dac283d56 /gdb/monitor.c | |
parent | 76ef4165507354d59b8f374404f735b97b09f79f (diff) | |
download | gdb-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.c | 247 |
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 = { |