aboutsummaryrefslogtreecommitdiff
path: root/gdb/monitor.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1995-03-30 01:47:32 +0000
committerStu Grossman <grossman@cygnus>1995-03-30 01:47:32 +0000
commita706069fdb9f5f49d08bfb83e831020e8ec5b9dd (patch)
treef46f0242bddba3775c0b5d906df3825b345c42ff /gdb/monitor.c
parent6d7bcd2f26b7b2764af72234faf1830809ca49b5 (diff)
downloadgdb-a706069fdb9f5f49d08bfb83e831020e8ec5b9dd.zip
gdb-a706069fdb9f5f49d08bfb83e831020e8ec5b9dd.tar.gz
gdb-a706069fdb9f5f49d08bfb83e831020e8ec5b9dd.tar.bz2
start-sanitize-gdbtk
* Makefile.in (gdbtk.o): Use X11_CFLAGS to provide alternate locations (per-host) for X11 include files. * config/pa/hppahpux.mh (XM_CLIBS): Add -L/usr/lib/X11R5 to force the use of R5 libs. (X11_CFLAGS): Add this to indicate the locs of the R5 include files. end-sanitize-gdbtk * monitor.c monitor.h remote-est.c rom68k-rom.c: Add start of support for interrupting target. * monitor.c (monitor_open): Send stop command before doing anything else. * (monitor_load_srec): Fix record size calculation to prevent end of segment from getting trashed. * rom68k-rom.c: Update to latest version of struct monitor_ops. * config/sparc/tm-sparc.h (FIX_CALL_DUMMY): Fix byte-order problems. Makes DOS hosted function calling work. * sparclite/crt0.s: Define _start to make COFF happy. * testsuite/config/rom68k.exp (gdb_target_rom68k): Use $targetname, $serialport and $baud instead of hardwired variables. * testsuite/gdb.base/{sigall.exp signals.exp}: Skip these if the target doesn't support signals.
Diffstat (limited to 'gdb/monitor.c')
-rw-r--r--gdb/monitor.c712
1 files changed, 433 insertions, 279 deletions
diff --git a/gdb/monitor.c b/gdb/monitor.c
index 4ac3485..7526d33 100644
--- a/gdb/monitor.c
+++ b/gdb/monitor.c
@@ -41,6 +41,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "monitor.h"
#include "gdbcmd.h"
#include "inferior.h"
+#include "regex.h"
static void monitor_command PARAMS ((char *args, int fromtty));
static void monitor_load_srec PARAMS ((char *args, int protocol));
@@ -51,8 +52,6 @@ static void make_xmodem_packet PARAMS ((unsigned char *packet,
int len));
static void print_xmodem_packet PARAMS ((char *packet));
-static void monitor_load_ascii_srec PARAMS ((char *file, int fromtty));
-
static int monitor_make_srec PARAMS ((char *buffer, int type,
CORE_ADDR memaddr,
unsigned char *myaddr, int len));
@@ -60,6 +59,22 @@ static int monitor_make_srec PARAMS ((char *buffer, int type,
static void monitor_fetch_register PARAMS ((int regno));
static void monitor_store_register PARAMS ((int regno));
+static void monitor_close PARAMS ((int quitting));
+static void monitor_detach PARAMS ((char *args, int from_tty));
+static void monitor_resume PARAMS ((int pid, int step, enum target_signal sig));
+static int monitor_wait PARAMS ((int pid, struct target_waitstatus *status));
+static void monitor_fetch_registers PARAMS ((int regno));
+static void monitor_store_registers PARAMS ((int regno));
+static void monitor_prepare_to_store PARAMS ((void));
+static int monitor_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len, int write, struct target_ops *target));
+static void monitor_files_info PARAMS ((struct target_ops *ops));
+static int monitor_insert_breakpoint PARAMS ((CORE_ADDR addr, char *shadow));
+static int monitor_remove_breakpoint PARAMS ((CORE_ADDR addr, char *shadow));
+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 int from_hex PARAMS ((int a));
static unsigned long get_hex_word PARAMS ((void));
@@ -89,6 +104,20 @@ static int expect_prompt PARAMS ((char *buf, int buflen));
static serial_t monitor_desc = NULL;
+/* Pointer to regexp pattern matching data */
+
+static struct re_pattern_buffer register_pattern;
+
+/* Element 0 points to start of register name, and element 1 points to the
+ start of the register value. */
+
+static struct re_registers register_strings;
+
+static char fastmap[256];
+
+static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when
+ monitor_wait wakes up. */
+
/* These definitions are for xmodem protocol. */
#define SOH 0x01
@@ -102,36 +131,6 @@ static serial_t monitor_desc = NULL;
#define XMODEM_PACKETSIZE 131 /* the packet size is ALWAYS 132 (zero based) */
#define XMODEM 1
-static unsigned char output_buf[0x200];
-static int obp;
-
-static void
-debug_save_output (buf, len)
- unsigned char *buf;
- int len;
-{
-#if 0
- for (; len > 0; len--)
- output_buf[obp++ & 0x1ff] = *buf++;
-#else
- fputs_unfiltered (buf, gdb_stdout);
-#endif
-}
-
-static unsigned char input_buf[0x200];
-static int ibp;
-
-static void
-debug_save_input_char (c)
- int c;
-{
-#if 0
- input_buf[ibp++ & 0x1ff] = c;
-#else
- fputc_unfiltered (c, gdb_stdout);
-#endif
-}
-
/* printf_monitor -- send data to monitor. Works just like printf. */
static void
@@ -149,7 +148,7 @@ printf_monitor (va_alist)
vsprintf (buf, pattern, args);
if (remote_debug > 0)
- debug_save_output (buf, strlen (buf));
+ fputs_unfiltered (buf, gdb_stderr);
if (strlen (buf) > PBUFSIZ)
error ("printf_monitor(): string too long");
@@ -182,24 +181,23 @@ readchar (timeout)
c = SERIAL_READCHAR (monitor_desc, timeout);
if (remote_debug > 0)
- debug_save_input_char (c & 0x7f);
+ fputc_unfiltered (c, gdb_stderr);
if (c >= 0)
return c & 0x7f;
if (c == SERIAL_TIMEOUT)
- {
- if (timeout == 0)
- return c; /* Polls shouldn't generate timeout errors */
- error ("Timeout reading from remote system.");
- }
+ error ("Timeout reading from remote system.");
+
perror_with_name ("remote-monitor");
}
/* Scan input from the remote system, until STRING is found. If BUF is non-
- zero, then collect input until either STRING has been collected or BUFLEN
- chars have been collected. If input overflows BUF because STRING can't be
- found, return -1, else return number of chars in BUF (including STRING). */
+ zero, then collect input until we have collected either STRING or BUFLEN-1
+ chars. In either case we terminate BUF with a 0. If input overflows BUF
+ because STRING can't be found, return -1, else return number of chars in BUF
+ (minus the terminating NUL). Note that in the non-overflow case, STRING
+ will be at the end of BUF. */
static int
expect (string, buf, buflen)
@@ -216,8 +214,9 @@ expect (string, buf, buflen)
{
if (buf)
{
- if (buflen <= 0)
+ if (buflen < 2)
{
+ *buf = '\000';
immediate_quit = 0;
return -1;
}
@@ -235,7 +234,13 @@ expect (string, buf, buflen)
{
immediate_quit = 0;
- return obuflen - buflen;
+ if (buf)
+ {
+ *buf++ = '\000';
+ return obuflen - buflen;
+ }
+ else
+ return 0;
}
}
else
@@ -311,6 +316,10 @@ monitor_open (args, mon_ops, from_tty)
{
char *name;
int i;
+ char **p;
+
+ if (mon_ops->magic != MONITOR_OPS_MAGIC)
+ error ("Magic number of monitor_ops struct wrong.");
targ_ops = mon_ops->target;
name = targ_ops->to_shortname;
@@ -321,6 +330,24 @@ monitor_open (args, mon_ops, from_tty)
target_preopen (from_tty);
+ /* Setup pattern for register dump */
+
+ if (mon_ops->register_pattern)
+ {
+ int tmp;
+ char *val;
+
+ register_pattern.fastmap = fastmap;
+ tmp = re_set_syntax (RE_SYNTAX_EMACS);
+ val = re_compile_pattern (mon_ops->register_pattern,
+ strlen (mon_ops->register_pattern),
+ &register_pattern);
+ re_set_syntax (tmp);
+ if (val)
+ error ("Can't compiler register pattern string: %s!", val);
+ re_compile_fastmap (&register_pattern);
+ }
+
unpush_target (targ_ops);
if (dev_name)
@@ -351,16 +378,25 @@ monitor_open (args, mon_ops, from_tty)
current_monitor = mon_ops;
- /* see if the target is alive. For a ROM monitor, we can just try to
- force the prompt to print a few times. */
+ /* See if we can wake up the monitor. First, try sending a stop sequence,
+ then send the init strings. Last, remove all breakpoints. */
+
+ monitor_stop ();
/* wake up the monitor and see if it's alive */
- printf_monitor (mon_ops->init);
- expect_prompt (NULL, 0); /* See if we get a prompt */
+ for (p = mon_ops->init; *p != NULL; p++)
+ {
+ printf_monitor (*p);
+ expect_prompt (NULL, 0);
+ }
+
+ /* Remove all breakpoints */
- /* try again to be sure */
- printf_monitor (mon_ops->init);
- expect_prompt (NULL, 0); /* See if we get a prompt */
+ if (mon_ops->clr_all_break)
+ {
+ printf_monitor (mon_ops->clr_all_break);
+ expect_prompt (NULL, 0);
+ }
/* Setup the suffixes for the `set remoteloadtype' command */
@@ -387,7 +423,7 @@ monitor_open (args, mon_ops, from_tty)
inferior_pid = 42000; /* Make run command think we are busy... */
- printf_monitor ("\r");
+ printf_monitor ("\r"); /* Give monitor_wait something to read */
start_remote ();
}
@@ -395,7 +431,7 @@ monitor_open (args, mon_ops, from_tty)
/* Close out all files and local state before this target loses
control. */
-void
+static void
monitor_close (quitting)
int quitting;
{
@@ -407,7 +443,7 @@ monitor_close (quitting)
/* Terminate the open connection to the remote debugger. Use this
when you want to detach and do something else with your gdb. */
-void
+static void
monitor_detach (args, from_tty)
char *args;
int from_tty;
@@ -417,9 +453,35 @@ monitor_detach (args, from_tty)
printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
}
+/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */
+
+char *
+monitor_supply_register (regno, valstr)
+ int regno;
+ char *valstr;
+{
+ unsigned LONGEST val;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+ char *p;
+
+ val = strtoul (valstr, &p, 16);
+
+ if (val == 0 && valstr == p)
+ error ("monitor_supply_register (%d): bad value from monitor: %s.",
+ regno, valstr);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
+
+ supply_register (regno, regbuf);
+
+ return p;
+}
+
/* Tell the remote machine to resume. */
-void
+static void
monitor_resume (pid, step, sig)
int pid, step;
enum target_signal sig;
@@ -427,31 +489,86 @@ monitor_resume (pid, step, sig)
if (step)
printf_monitor (STEP_CMD);
else
- printf_monitor (CONT_CMD);
+ {
+ printf_monitor (CONT_CMD);
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ }
+}
+
+/* Parse the output of a register dump command. A monitor specific regexp is
+ used to extract individual register descriptions of the 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 *
+parse_register_dump (buf, len)
+ char *buf;
+ int len;
+{
+ while (1)
+ {
+ int regnamelen, vallen;
+ char *regname, *val;
+
+ if (re_search (&register_pattern, buf, len, 0, len,
+ &register_strings) == -1)
+ break;
+
+ regnamelen = register_strings.end[1] - register_strings.start[1];
+ regname = buf + register_strings.start[1];
+ vallen = register_strings.end[2] - register_strings.start[2];
+ val = buf + register_strings.start[2];
+
+ current_monitor->supply_register (regname, regnamelen, val, vallen);
+
+ buf += register_strings.end[0];
+ len -= register_strings.end[0];
+ }
}
/* Wait until the remote machine stops, then return, storing status in
status just as `wait' would. */
-int
+static int
monitor_wait (pid, status)
int pid;
struct target_waitstatus *status;
{
int old_timeout = timeout;
+ char buf[512];
+ int resp_len;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
timeout = -1; /* Don't time out -- user program is running. */
- expect_prompt (NULL, 0); /* Wait for prompt, outputting extraneous text */
+ do
+ {
+ resp_len = expect_prompt (buf, sizeof (buf));
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_TRAP;
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
timeout = old_timeout;
+ if (dump_reg_flag && current_monitor->dump_registers)
+ {
+ dump_reg_flag = 0;
+
+ printf_monitor (current_monitor->dump_registers);
+ resp_len = expect_prompt (buf, sizeof (buf));
+ }
+
+ if (current_monitor->register_pattern)
+ parse_register_dump (buf, resp_len);
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
return inferior_pid;
}
@@ -462,10 +579,8 @@ static void
monitor_fetch_register (regno)
int regno;
{
- unsigned LONGEST val;
- unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
char buf[200];
- char *p, *p1;
+ char *p;
char *name;
int resp_len;
@@ -516,22 +631,12 @@ monitor_fetch_register (regno)
else
p = buf;
- val = strtoul (p, &p1, 16);
-
- if (val == 0 && p == p1)
- error ("monitor_fetch_register (%d): bad value from monitor: %.*s.",
- regno, resp_len, buf);
-
- /* supply register stores in target byte order, so swap here */
-
- store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
-
- supply_register (regno, regbuf);
+ monitor_supply_register (regno, p);
}
/* Read the remote registers into the block regs. */
-void
+static void
monitor_fetch_registers (regno)
int regno;
{
@@ -574,7 +679,7 @@ monitor_store_register (regno)
/* Store the remote registers. */
-void
+static void
monitor_store_registers (regno)
int regno;
{
@@ -594,14 +699,15 @@ monitor_store_registers (regno)
that registers contains all the registers from the program being
debugged. */
-void
+static void
monitor_prepare_to_store ()
{
/* Do nothing, since we can store individual regs */
}
-void
-monitor_files_info ()
+static void
+monitor_files_info (ops)
+ struct target_ops *ops;
{
printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baud_rate);
}
@@ -612,18 +718,59 @@ monitor_write_memory (memaddr, myaddr, len)
unsigned char *myaddr;
int len;
{
- /* send the memory deposit command */
+ unsigned LONGEST val;
+ char *cmd;
+ int i;
- printf_monitor (current_monitor->setmem.cmd, memaddr, *myaddr);
+ /* Use memory fill command for leading 0 bytes. */
-/* It's possible that there are actually some monitors out there that will
- prompt you when you deposit to memory. In that case, you may need to add
- some code here to deal with TERM and TERM_CMD (see monitor_read_memory to
- get an idea of what's needed...) */
+ if (current_monitor->fill)
+ {
+ for (i = 0; i < len; i++)
+ if (myaddr[i] != 0)
+ break;
+
+ if (i > 4) /* More than 4 zeros is worth doing */
+ {
+ if (current_monitor->flags & MO_FILL_USES_ADDR)
+ printf_monitor (current_monitor->fill, memaddr, memaddr + i, 0);
+ else
+ printf_monitor (current_monitor->fill, memaddr, i, 0);
+
+ expect_prompt (NULL, 0);
+
+ return i;
+ }
+ }
+
+ if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll)
+ {
+ len = 8;
+ cmd = current_monitor->setmem.cmdll;
+ }
+ else if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl)
+ {
+ len = 4;
+ cmd = current_monitor->setmem.cmdl;
+ }
+ else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->setmem.cmdw)
+ {
+ len = 2;
+ cmd = current_monitor->setmem.cmdw;
+ }
+ else
+ {
+ len = 1;
+ cmd = current_monitor->setmem.cmdb;
+ }
+
+ val = extract_unsigned_integer (myaddr, len);
+
+ printf_monitor (cmd, memaddr, val);
expect_prompt (NULL, 0);
- return 1;
+ return len;
}
/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory
@@ -642,10 +789,13 @@ monitor_read_memory (memaddr, myaddr, len)
char *p, *p1;
char *name;
int resp_len;
+ int i;
+
+ len = min (len, 16);
/* send the memory examine command */
- printf_monitor (current_monitor->getmem.cmd, memaddr);
+ printf_monitor (current_monitor->getmem.cmdb, memaddr, len);
/* If TERM is present, we wait for that to show up. Also, (if TERM is
present), we will send TERM_CMD if that is present. In any case, we collect
@@ -670,8 +820,8 @@ monitor_read_memory (memaddr, myaddr, len)
resp_len = expect_prompt (buf, sizeof buf); /* get response */
/* If RESP_DELIM is specified, we search for that as a leading delimiter for
- the register value. Otherwise, we just start searching from the start of
- the buf. */
+ the values. Otherwise, we just start searching from the start of the buf.
+ */
if (current_monitor->getmem.resp_delim)
{
@@ -684,20 +834,24 @@ monitor_read_memory (memaddr, myaddr, len)
else
p = buf;
- val = strtoul (p, &p1, 16);
+ for (i = len; i > 0; i--)
+ {
+ val = strtoul (p, &p1, 16);
- if (val == 0 && p == p1)
- error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.", memaddr,
- resp_len, buf);
+ if (val == 0 && p == p1)
+ error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.", memaddr,
+ resp_len, buf);
- *myaddr = val;
+ p = p1;
+ *myaddr++ = val;
+ }
- return 1; /* Got 1 byte */
+ return len;
}
/* FIXME-someday! merge these two. */
-int
+static int
monitor_xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
@@ -711,20 +865,34 @@ monitor_xfer_memory (memaddr, myaddr, len, write, target)
return monitor_read_memory (memaddr, myaddr, len);
}
-void
-monitor_kill (args, from_tty)
- char *args;
- int from_tty;
+static void
+monitor_kill ()
{
return; /* ignore attempts to kill target system */
}
+/* All we actually do is set the PC to the start address of exec_bfd, and start
+ the program at that point. */
+
+static void
+monitor_create_inferior (exec_file, args, env)
+ char *exec_file;
+ char *args;
+ char **env;
+{
+ if (args && (*args != '\000'))
+ error ("Args are not supported by the monitor.");
+
+ clear_proceed_status ();
+ proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
/* Clean up when a program exits.
The program actually lives on in the remote processor's RAM, and may be
run again without a download. Don't leave it full of breakpoint
instructions. */
-void
+static void
monitor_mourn_inferior ()
{
unpush_target (targ_ops);
@@ -737,7 +905,7 @@ static CORE_ADDR breakaddr[NUM_MONITOR_BREAKPOINTS] = {0};
/* Tell the monitor to add a breakpoint. */
-int
+static int
monitor_insert_breakpoint (addr, shadow)
CORE_ADDR addr;
char *shadow;
@@ -762,7 +930,7 @@ monitor_insert_breakpoint (addr, shadow)
/* Tell the monitor to remove a breakpoint. */
-int
+static int
monitor_remove_breakpoint (addr, shadow)
CORE_ADDR addr;
char *shadow;
@@ -775,10 +943,10 @@ monitor_remove_breakpoint (addr, shadow)
{
breakaddr[i] = 0;
/* some monitors remove breakpoints based on the address */
- if (CLR_BREAK_ADDR)
- printf_monitor(CLR_BREAK_CMD, addr);
+ if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
+ printf_monitor (CLR_BREAK_CMD, addr);
else
- printf_monitor(CLR_BREAK_CMD, i);
+ printf_monitor (CLR_BREAK_CMD, i);
expect_prompt (NULL, 0);
return 0;
}
@@ -804,105 +972,57 @@ monitor_remove_breakpoint (addr, shadow)
* protocol.
*/
-void
-monitor_load (file, fromtty)
+static void
+monitor_load (file, from_tty)
char *file;
- int fromtty;
+ int from_tty;
{
/* default, load a binary */
if (STREQ (loadtype_str, "default"))
- {
- error ("default load type not supported.");
- }
+ error ("default load type not supported.");
/* load an srecord by converting */
- if ((STREQ (loadtype_str, "srec")) && STREQ (loadproto_str, "xmodem"))
- {
- monitor_load_srec (file, XMODEM);
- return;
- }
+ else if ((STREQ (loadtype_str, "srec")) && STREQ (loadproto_str, "xmodem"))
+ monitor_load_srec (file, XMODEM);
/* load an srecord by converting */
- if (STREQ (loadtype_str, "srec"))
- {
- monitor_load_srec (file, 0); /* if from a binary */
- return;
- }
+ else if (STREQ (loadtype_str, "srec"))
+ monitor_load_srec (file, 0); /* if from a binary */
/* load an srecord by converting */
- if (STREQ (loadtype_str, "none"))
- {
- error ("Unimplemented");
- return;
- }
+ else if (STREQ (loadtype_str, "none"))
+ error ("Unimplemented");
/* load an srecord file */
- if (STREQ (loadproto_str, "none"))
- {
- monitor_load_ascii_srec (file, fromtty); /* if from a binary */
- return;
- }
+ else if (STREQ (loadproto_str, "none"))
+ monitor_load_srec (file, 0);
- if (STREQ (loadproto_str, "xmodem"))
- {
- monitor_load_srec (file, XMODEM);
- return;
- }
-}
+ else if (STREQ (loadproto_str, "xmodem"))
+ monitor_load_srec (file, XMODEM);
-/* Download an ASCII srecord file. */
+/* Finally, make the PC point at the start address */
-#define DOWNLOAD_LINE_SIZE 100
+ write_pc (bfd_get_start_address (exec_bfd));
-static void
-monitor_load_ascii_srec (file, fromtty)
- char *file;
- int fromtty;
-{
- FILE *download;
- char buf[DOWNLOAD_LINE_SIZE];
- int i, bytes_read;
+ inferior_pid = 0; /* No process now */
- download = fopen (file, "r");
- if (download == NULL)
- {
- error ("%s does not exist", file);
- return;
- }
+/* This is necessary because many things were based on the PC at the time that
+ we attached to the monitor, which is no longer valid now that we have loaded
+ new code (and just changed the PC). Another way to do this might be to call
+ normal_stop, except that the stack may not be valid, and things would get
+ horribly confused... */
- printf_monitor (LOAD_CMD);
- sleep (1);
- while (!feof (download))
- {
- bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
- if (hashmark)
- {
- putchar_unfiltered ('.');
- gdb_flush (gdb_stdout);
- }
- if (SERIAL_WRITE (monitor_desc, buf, bytes_read))
- {
- fprintf_unfiltered (stderr, "SERIAL_WRITE failed: (while downloading) %s\n",
- safe_strerror (errno));
- break;
- }
- i = 0;
- while (i++ <=200) {} ; /* Ugly HACK, probably needs flow control */
- if (bytes_read < DOWNLOAD_LINE_SIZE)
- {
- if (!feof (download))
- error ("Only read %d bytes\n", bytes_read);
- break;
- }
- }
-
- if (hashmark)
- putchar_unfiltered ('\n');
+ clear_symtab_users ();
+}
+
+static void
+monitor_stop ()
+{
+ if (!current_monitor->stop)
+ return;
- if (!feof (download))
- error ("Never got EOF while downloading");
+ printf_monitor(current_monitor->stop);
expect_prompt (NULL, 0);
- fclose (download);
}
/* Put a command string, in args, out to MONITOR. Output from MONITOR
@@ -910,11 +1030,13 @@ monitor_load_ascii_srec (file, fromtty)
read the characters ourseleves here cause of a nasty echo. */
static void
-monitor_command (args, fromtty)
+monitor_command (args, from_tty)
char *args;
- int fromtty;
+ int from_tty;
{
char *p;
+ int resp_len;
+ char buf[1000];
p = PROMPT;
@@ -924,9 +1046,11 @@ monitor_command (args, fromtty)
/* Send the command. Note that if no args were supplied, then we're
just sending the monitor a newline, which is sometimes useful. */
- printf_monitor ("%s\n", (args ? args : ""));
+ printf_monitor ("%s\r", (args ? args : ""));
- expect_prompt (NULL, 0);
+ resp_len = expect_prompt (buf, sizeof buf);
+
+ fputs_unfiltered (buf, gdb_stdout); /* Output the response */
}
/* Download a binary file by converting it to srecords. This
@@ -958,12 +1082,13 @@ monitor_load_srec (args, protocol)
char packet[XMODEM_PACKETSIZE];
int i;
int retries;
- int type = 0; /* default to a type 0, header record */
int srec_frame = 57; /* FIXME: this must be 57 There is 12 bytes
of header, and 2 bytes of checksum at the end.
The problem is an xmodem packet holds exactly
128 bytes. */
+ buffer = alloca (srec_frame * 2 + 256);
+
abfd = bfd_openr (args, 0);
if (!abfd)
{
@@ -978,84 +1103,74 @@ monitor_load_srec (args, protocol)
}
printf_monitor (LOAD_CMD); /* tell the monitor to load */
- sleep (3);
+ if (current_monitor->loadresp)
+ expect (current_monitor->loadresp, NULL, 0);
+
/* get the NAK from the target */
- if (protocol == XMODEM)
+ if (protocol == XMODEM && !GETNAK)
{
- if (!GETNAK)
- {
- printf_monitor ("%c", EOT);
- error ("Never got the NAK to start loading");
- }
+ printf_monitor ("%c", EOT);
+ error ("Never got the NAK to start loading");
}
- s = abfd->sections;
- while (s != (asection *) NULL)
- {
- if (s->flags & SEC_LOAD)
- {
- buffer = xmalloc (srec_frame);
-
- printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
- s->name, s->vma, s->vma + s->_raw_size);
- gdb_flush (gdb_stdout);
- for (i = 0; i < s->_raw_size; i += srec_frame)
- {
- if (srec_frame > s->_raw_size - i)
- srec_frame = s->_raw_size - i;
-
- bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
- monitor_make_srec (srec, type, s->vma + i, buffer, srec_frame);
- /* send a packet using xmodem */
- if (protocol == XMODEM)
- {
- make_xmodem_packet (packet, srec, XMODEM_DATASIZE);
- write_monitor (packet, XMODEM_PACKETSIZE+1);
- retries = 0;
- while (retries++ <= 3)
- {
- /* Resend packet */
- if (GETNAK)
- {
- sleep (1);
- /* send it again */
- write_monitor (packet, XMODEM_PACKETSIZE+1);
- if (GETACK) /* ACKnowledged, get next data chunk */
- break;
- }
- else
- { /* assume we got an ACK */
- if (hashmark)
- {
- putchar_unfiltered ('#');
- gdb_flush (gdb_stdout);
- }
- break;
- }
- }
- if (retries >= 4)
- { /* too many tries, must be hosed */
- printf_monitor ("%c", EOT);
- error ("Never got a ACK after sending an xmodem packet");
- }
- }
- else
- { /* no protocols at all */
- printf_monitor ("%s\n", srec);
- }
- if (hashmark)
- {
- putchar_unfiltered ('#');
- gdb_flush (gdb_stdout);
- }
- type = 3; /* switch to a 4 byte address record */
- gdb_flush (gdb_stdout);
- }
- free (buffer);
- }
- s = s->next;
- }
- putchar_unfiltered ('\n');
+ for (s = abfd->sections; s; s = s->next)
+ if (s->flags & SEC_LOAD)
+ {
+ printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
+ s->vma + s->_raw_size);
+ gdb_flush (gdb_stdout);
+ for (i = 0; i < s->_raw_size; i += srec_frame)
+ {
+ int numbytes;
+
+ numbytes = min (srec_frame, s->_raw_size - i);
+
+ bfd_get_section_contents (abfd, s, buffer, i, numbytes);
+ monitor_make_srec (srec, 3, s->vma + i, buffer, numbytes);
+
+ /* send a packet using xmodem */
+ if (protocol == XMODEM)
+ {
+ make_xmodem_packet (packet, srec, XMODEM_DATASIZE);
+ write_monitor (packet, XMODEM_PACKETSIZE+1);
+
+ for (retries = 3; retries >= 0; retries++)
+ {
+ if (GETACK) /* ACKnowledged, get next data chunk */
+ break;
+
+ /* Resend packet */
+
+ sleep (1);
+ /* send it again */
+ write_monitor (packet, XMODEM_PACKETSIZE+1);
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('-');
+ gdb_flush (gdb_stdout);
+ }
+ }
+ if (retries < 0)
+ { /* too many tries, must be hosed */
+ printf_monitor ("%c", EOT);
+ error ("Never got a ACK after sending an xmodem packet");
+ }
+ }
+ else
+ printf_monitor ("%s\n", srec); /* no protocols at all */
+
+ if (hashmark)
+ {
+ putchar_unfiltered ('#');
+ gdb_flush (gdb_stdout);
+ }
+ } /* Per-packet (or S-record) loop */
+ putchar_unfiltered ('\n');
+ } /* Loadable sections */
+
+ if (hashmark)
+ putchar_unfiltered ('\n');
/* Write a type 7 terminator record. no data for a type 7, and there
is no data, so len is 0. */
@@ -1066,27 +1181,17 @@ monitor_load_srec (args, protocol)
monitor_make_srec (srec, 7, abfd->start_address, "", 0);
make_xmodem_packet (packet, srec, XMODEM_DATASIZE);
write_monitor (packet, XMODEM_PACKETSIZE+1);
+ printf_monitor ("%c", EOT);
+ if (!GETACK)
+ error ("Never got ACK after sending EOT");
}
else
{
monitor_make_srec (srec, 7, abfd->start_address, "", 0);
printf_monitor ("%s\n", srec);
}
- if (protocol == XMODEM)
- {
- printf_monitor ("%c", EOT);
- if (!GETACK)
- error ("Never got ACK after sending EOT");
- }
- if (hashmark)
- putchar_unfiltered ('\n');
-
expect_prompt (NULL, 0);
-
-/* Finally, make the PC point at the start address */
-
- write_register (PC_REGNUM, bfd_get_start_address (abfd));
}
/* Get an ACK or a NAK from the target. returns 1 (true) or 0 (false)
@@ -1194,8 +1299,6 @@ monitor_make_srec (buffer, type, memaddr, myaddr, len)
/* Create the header for the srec. 4 is the number of bytes in the address,
and 1 is the number of bytes in the count. */
- if (type == 0) /* FIXME: type 0 is optional */
- type = 3; /* so use data as it works */
sprintf (buf, "S%d%02X%08X", type, len + 4 + 1, memaddr);
buf += 12;
@@ -1326,6 +1429,57 @@ from_hex (a)
error ("Reply contains invalid hex digit 0x%x", a);
}
+static struct target_ops monitor_ops = {
+ NULL, /* to_shortname */
+ NULL, /* to_longname */
+ NULL, /* to_doc */
+ NULL, /* to_open */
+ monitor_close, /* to_close */
+ NULL, /* to_attach */
+ monitor_detach, /* to_detach */
+ monitor_resume, /* to_resume */
+ monitor_wait, /* to_wait */
+ monitor_fetch_registers, /* to_fetch_registers */
+ monitor_store_registers, /* to_store_registers */
+ monitor_prepare_to_store, /* to_prepare_to_store */
+ monitor_xfer_memory, /* to_xfer_memory */
+ monitor_files_info, /* to_files_info */
+ monitor_insert_breakpoint, /* to_insert_breakpoint */
+ monitor_remove_breakpoint, /* to_remove_breakpoint */
+ 0, /* to_terminal_init */
+ 0, /* to_terminal_inferior */
+ 0, /* to_terminal_ours_for_output */
+ 0, /* to_terminal_ours */
+ 0, /* to_terminal_info */
+ monitor_kill, /* to_kill */
+ monitor_load, /* to_load */
+ 0, /* to_lookup_symbol */
+ monitor_create_inferior, /* to_create_inferior */
+ monitor_mourn_inferior, /* to_mourn_inferior */
+ 0, /* to_can_run */
+ 0, /* to_notice_signals */
+ monitor_stop, /* to_stop */
+ process_stratum, /* to_stratum */
+ 0, /* to_next */
+ 1, /* to_has_all_memory */
+ 1, /* to_has_memory */
+ 1, /* to_has_stack */
+ 1, /* to_has_registers */
+ 1, /* to_has_execution */
+ 0, /* sections */
+ 0, /* sections_end */
+ OPS_MAGIC /* to_magic */
+};
+
+/* Init the target_ops structure pointed at by OPS */
+
+void
+init_monitor_ops (ops)
+ struct target_ops *ops;
+{
+ memcpy (ops, &monitor_ops, sizeof monitor_ops);
+}
+
/* Define additional commands that are usually only used by monitors. */
void