updating to match changes made to progressive/build-all.mk
[deliverable/binutils-gdb.git] / gdb / monitor.c
CommitLineData
51d6a954
RS
1/* Remote debugging interface for boot monitors, for GDB.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* This file was derived from various remote-* modules. It is a collection
22 of generic support functions so GDB can talk directly to a ROM based
23 monitor. This saves use from having to hack an exception based handler
24 into existance, and makes for quick porting.
25
26 This module talks to a debug monitor called 'MONITOR', which
27 We communicate with MONITOR via either a direct serial line, or a TCP
28 (or possibly TELNET) stream to a terminal multiplexor,
29 which in turn talks to the target board.
30*/
31
32#include "defs.h"
33#include "gdbcore.h"
34#include "target.h"
35#include "wait.h"
36#include <varargs.h>
37#include <signal.h>
38#include <string.h>
39#include <sys/types.h>
40#include "command.h"
41#include "serial.h"
42#include "monitor.h"
43#include "remote-utils.h"
44
45#ifdef HAVE_TERMIO
46# define TERMINAL struct termios
47#else
48# define TERMINAL struct sgttyb
49#endif
50
51struct monitor_ops *current_monitor;
52extern struct cmd_list_element *setlist;
53extern struct cmd_list_element *unsetlist;
54struct cmd_list_element *showlist;
55
56static int hashmark; /* flag set by "set hash" */
57
58/* FIXME: Replace with sr_get_debug (). */
59#define LOG_FILE "monitor.log"
60#if defined (LOG_FILE)
61FILE *log_file;
62#endif
63
64static int timeout = 24;
65
66/* Descriptor for I/O to remote machine. Initialize it to NULL so that
67 monitor_open knows that we don't have a file open when the program starts.
68 */
69static serial_t monitor_desc = NULL;
70
71/* sets the download protocol, choices are srec, generic, boot */
72char *loadtype;
73static char *loadtype_str;
74static void set_loadtype_command();
75
76/*
77 * set_loadtype_command -- set the type for downloading. Check to make
78 * sure you have a support protocol for this target.
79 */
80static void
81set_loadtype_command (ignore, from_tty, c)
82 char *ignore;
83 int from_tty;
84 struct cmd_list_element *c;
85{
86#if 0
87 char *type;
88 if (strcmp (LOADTYPES, "")) {
89 error ("No loadtype set");
90 return;
91 }
92
93 type = strtok(LOADTYPES, ",");
94 if (STREQ (type, (*(char **) c->var))) {
95 loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
96 return;
97 }
98
99 while (type = strtok (NULL, ",") != (char *)NULL)
100 if (STREQ (type, (*(char **) c->var)))
101 loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
102#endif
103 loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
104}
105
106/*
107 * printf_monitor -- send data to monitor. Works just like printf.
108 */
109static void
110printf_monitor(va_alist)
111 va_dcl
112{
113 va_list args;
114 char *pattern;
115 char buf[200];
116 int i;
117
118 va_start(args);
119
120 pattern = va_arg(args, char *);
121
122 vsprintf(buf, pattern, args);
123
124 if (sr_get_debug() > 3)
125 printf ("Sending to monitor,\r\n\t\"%s\".\r\n", buf);
126
127 if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
128 fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
129}
130
131/* Read a character from the remote system, doing all the fancy
132 timeout stuff. */
133static int
134readchar(timeout)
135 int timeout;
136{
137 int c;
138
139 c = SERIAL_READCHAR(monitor_desc, timeout);
140
141 if (sr_get_debug())
142 putchar(c & 0x7f);
143
144#ifdef LOG_FILE
145 if (isascii (c))
146 putc(c & 0x7f, log_file);
147#endif
148
149 if (c >= 0)
150 return c & 0x7f;
151
152 if (c == SERIAL_TIMEOUT)
153 {
154 if (timeout == 0)
155 return c; /* Polls shouldn't generate timeout errors */
156
157 error("Timeout reading from remote system.");
158 }
159
160 perror_with_name("remote-monitor");
161}
162
163/* Scan input from the remote system, until STRING is found. If DISCARD is
164 non-zero, then discard non-matching input, else print it out.
165 Let the user break out immediately. */
166static void
167expect (string, discard)
168 char *string;
169 int discard;
170{
171 char *p = string;
172 int c;
173
174
175 if (sr_get_debug())
176 printf ("Expecting \"%s\".\n", string);
177
178 immediate_quit = 1;
179 while (1) {
180 c = readchar(timeout);
181 if (!isascii (c))
182 continue;
183 if (c == *p++) {
184 if (*p == '\0') {
185 immediate_quit = 0;
186 if (sr_get_debug())
187 printf ("\nMatched\n");
188 return;
189 }
190 } else {
191 if (!discard) {
192 fwrite(string, 1, (p - 1) - string, stdout);
193 putchar((char)c);
194 fflush(stdout);
195 }
196 p = string;
197 }
198 }
199}
200
201/* Keep discarding input until we see the MONITOR prompt.
202
203 The convention for dealing with the prompt is that you
204 o give your command
205 o *then* wait for the prompt.
206
207 Thus the last thing that a procedure does with the serial line
208 will be an expect_prompt(). Exception: monitor_resume does not
209 wait for the prompt, because the terminal is being handed over
210 to the inferior. However, the next thing which happens after that
211 is a monitor_wait which does wait for the prompt.
212 Note that this includes abnormal exit, e.g. error(). This is
213 necessary to prevent getting into states from which we can't
214 recover. */
215static void
216expect_prompt(discard)
217 int discard;
218{
219#if defined (LOG_FILE)
220 /* This is a convenient place to do this. The idea is to do it often
221 enough that we never lose much data if we terminate abnormally. */
222 fflush(log_file);
223#endif
224 expect (PROMPT, discard);
225}
226
227/*
228 * junk -- ignore junk characters. Returns a 1 if junk, 0 otherwise
229 */
230static int
231junk(ch)
232 char ch;
233{
234 switch (ch) {
235 case ' ':
236 case '-':
237 case '\t':
238 case '\r':
239 case '\n':
240 if (sr_get_debug() > 5)
241 printf ("Ignoring \'%c\'.\n", ch);
242 return 1;
243 default:
244 if (sr_get_debug() > 5)
245 printf ("Accepting \'%c\'.\n", ch);
246 return 0;
247 }
248}
249
250/*
251 * get_hex_digit -- Get a hex digit from the remote system & return its value.
252 * If ignore is nonzero, ignore spaces, newline & tabs.
253 */
254static int
255get_hex_digit(ignore)
256 int ignore;
257{
258 static int ch;
259 while (1) {
260 ch = readchar(timeout);
261 if (junk(ch))
262 continue;
263 if (sr_get_debug() > 4)
264 printf ("get_hex_digit() got a 0x%x(%c)\n", ch, ch);
265
266 if (ch >= '0' && ch <= '9')
267 return ch - '0';
268 else if (ch >= 'A' && ch <= 'F')
269 return ch - 'A' + 10;
270 else if (ch >= 'a' && ch <= 'f')
271 return ch - 'a' + 10;
272 else if (ch == ' ' && ignore)
273 ;
274 else {
275 expect_prompt(1);
276 error("Invalid hex digit from remote system.");
277 }
278 }
279}
280
281/* get_hex_byte -- Get a byte from monitor and put it in *BYT.
282 * Accept any number leading spaces.
283 */
284static void
285get_hex_byte (byt)
286 char *byt;
287{
288 int val;
289
290 val = get_hex_digit (1) << 4;
291 if (sr_get_debug() > 3)
292 printf ("\nget_hex_digit() -- Read first nibble 0x%x\n", val);
293
294 val |= get_hex_digit (0);
295 if (sr_get_debug() > 3)
296 printf ("\nget_hex_digit() -- Read second nibble 0x%x\n", val);
297 *byt = val;
298
299 if (sr_get_debug() > 3)
300 printf ("\nget_hex_digit() -- Read a 0x%x\n", val);
301}
302
303/*
304 * get_hex_word -- Get N 32-bit words from remote, each preceded by a space,
305 * and put them in registers starting at REGNO.
306 */
307static int
308get_hex_word ()
309{
310 long val;
311 int i;
312
313 val = 0;
314 for (i = 0; i < 8; i++)
315 val = (val << 4) + get_hex_digit (i == 0);
316
317 if (sr_get_debug() > 3)
318 printf ("\nget_hex_word() got a 0x%x.\n", val);
319
320 return val;
321}
322
323/* This is called not only when we first attach, but also when the
324 user types "run" after having attached. */
325void
326monitor_create_inferior (execfile, args, env)
327 char *execfile;
328 char *args;
329 char **env;
330{
331 int entry_pt;
332
333 if (args && *args)
334 error("Can't pass arguments to remote MONITOR process");
335
336 if (execfile == 0 || exec_bfd == 0)
337 error("No exec file specified");
338
339 entry_pt = (int) bfd_get_start_address (exec_bfd);
340
341#ifdef LOG_FILE
342 fputs ("\nIn Create_inferior()", log_file);
343#endif
344
345/* The "process" (board) is already stopped awaiting our commands, and
346 the program is already downloaded. We just set its PC and go. */
347
348 clear_proceed_status ();
349
350 /* Tell wait_for_inferior that we've started a new process. */
351 init_wait_for_inferior ();
352
353 /* Set up the "saved terminal modes" of the inferior
354 based on what modes we are starting it with. */
355 target_terminal_init ();
356
357 /* Install inferior's terminal modes. */
358 target_terminal_inferior ();
359
360 /* insert_step_breakpoint (); FIXME, do we need this? */
361
362 /* Let 'er rip... */
363 proceed ((CORE_ADDR)entry_pt, TARGET_SIGNAL_DEFAULT, 0);
364}
365
366/* Open a connection to a remote debugger.
367 NAME is the filename used for communication. */
368
369static int baudrate = 9600;
370static char dev_name[100];
371
372void
373monitor_open(args, name, from_tty)
374 char *args;
375 char *name;
376 int from_tty;
377{
378
379 if (args == NULL)
380 error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
381`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
382
383/* if (is_open) */
384 monitor_close(0);
385
386 strcpy(dev_name, args);
387 monitor_desc = SERIAL_OPEN(dev_name);
388
389 if (monitor_desc == NULL)
390 perror_with_name(dev_name);
391
392 if (baud_rate != -1)
393 {
394 if (SERIAL_SETBAUDRATE (monitor_desc, baud_rate))
395 {
396 SERIAL_CLOSE (monitor_desc);
397 perror_with_name (name);
398 }
399 }
400
401 SERIAL_RAW(monitor_desc);
402
403#if defined (LOG_FILE)
404 log_file = fopen (LOG_FILE, "w");
405 if (log_file == NULL)
406 perror_with_name (LOG_FILE);
407#endif
408
409 /* wake up the monitor and see if it's alive */
410 printf_monitor(INIT_CMD);
411 expect_prompt(1); /* See if we get a prompt */
412
413 /* try again to be sure */
414 printf_monitor(INIT_CMD);
415 expect_prompt(1); /* See if we get a prompt */
416
417 if (from_tty)
418 printf("Remote target %s connected to %s\n", TARGET_NAME, dev_name);
419
420
421}
422
423/*
424 * _close -- Close out all files and local state before this target loses control.
425 */
426
427void
428monitor_close (quitting)
429 int quitting;
430{
431 SERIAL_CLOSE(monitor_desc);
432 monitor_desc = NULL;
433
434#if defined (LOG_FILE)
435 if (log_file) {
436 if (ferror(log_file))
437 fprintf(stderr, "Error writing log file.\n");
438 if (fclose(log_file) != 0)
439 fprintf(stderr, "Error closing log file.\n");
440 }
441#endif
442}
443
444/* Terminate the open connection to the remote debugger.
445 Use this when you want to detach and do something else
446 with your gdb. */
447void
448monitor_detach (from_tty)
449 int from_tty;
450{
451 pop_target(); /* calls monitor_close to do the real work */
452 if (from_tty)
453 printf ("Ending remote %s debugging\n", target_shortname);
454}
455
456/*
457 * _resume -- Tell the remote machine to resume.
458 */
459void
460monitor_resume (pid, step, sig)
461 int pid, step;
462 enum target_signal sig;
463{
464#ifdef LOG_FILE
465 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
466#endif
467
468 if (step)
469 {
470 printf_monitor (STEP_CMD);
471 /* wait for the echo. */
472 expect (STEP_CMD, 1);
473 }
474 else
475 {
476 printf_monitor (GO_CMD);
477 /* swallow the echo. */
478 expect (GO_CMD, 1);
479 }
480}
481
482/*
483 * _wait -- Wait until the remote machine stops, then return,
484 * storing status in status just as `wait' would.
485 */
486
487int
488monitor_wait (pid, status)
489 int pid;
490 struct target_waitstatus *status;
491{
492 int old_timeout = timeout;
493#ifdef LOG_FILE
494 fputs ("\nIn wait ()", log_file);
495#endif
496
497 status->kind = TARGET_WAITKIND_EXITED;
498 status->value.integer = 0;
499
500 timeout = 0; /* Don't time out -- user program is running. */
501
502 expect_prompt(0); /* Wait for prompt, outputting extraneous text */
503
504 status->kind = TARGET_WAITKIND_STOPPED;
505 status->value.sig = TARGET_SIGNAL_TRAP;
506
507 timeout = old_timeout;
508
509 return 0;
510}
511
512/* Return the name of register number regno in the form input and output by
513 monitor. Currently, register_names just happens to contain exactly what
514 monitor wants. Lets take advantage of that just as long as possible! */
515
516static char *
517get_reg_name (regno)
518 int regno;
519{
520 static char buf[50];
521 const char *p;
522 char *b;
523
524 b = buf;
525
526 if (regno < 0)
527 return ("");
528
529 for (p = REGNAMES(regno); *p; p++)
530 *b++ = tolower(*p);
531
532 *b = '\000';
533
534 if (sr_get_debug() > 5)
535 printf ("Got name \"%s\" from regno #%d.\n", buf, regno);
536
f1ca4cbc
RS
537#ifdef LOG_FILE
538 fprintf (log_file, "Got name \"%s\" from regno #%d.\n", buf, regno);
539 fflush (log_file);
540#endif
541
51d6a954
RS
542 return buf;
543}
544
545/* read the remote registers into the block regs. */
546
547void
548monitor_fetch_registers ()
549{
550 int regno;
551
552 /* yeah yeah, i know this is horribly inefficient. but it isn't done
553 very often... i'll clean it up later. */
554
555 for (regno = 0; regno <= PC_REGNUM; regno++)
556 monitor_fetch_register(regno);
557}
558
559/*
f1ca4cbc
RS
560 * monitor_fetch_register -- fetch register REGNO, or all registers if REGNO
561 * is -1. Returns errno value.
51d6a954
RS
562 */
563void
564monitor_fetch_register (regno)
565 int regno;
566{
567 int val, j;
568
569#ifdef LOG_FILE
570 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
571 fflush (log_file);
572#endif
573
574 if (regno < 0) {
575 monitor_fetch_registers ();
576 } else {
577 char *name = get_reg_name (regno);
578 if (STREQ(name, ""))
579 return;
580 printf_monitor (ROMCMD(GET_REG), name); /* send the command */
581 expect (name, 1); /* then strip the leading garbage */
582 if (*ROMDELIM(GET_REG) != 0) { /* if there's a delimiter */
583 expect (ROMDELIM(GET_REG), 1);
584 }
585
586 val = get_hex_word(); /* get the value, ignore junk */
587 supply_register (regno, (char *) &val);
588
589 if (*ROMDELIM(GET_REG) != 0) {
f1ca4cbc 590/*** expect (ROMRES(GET_REG)); ***/
51d6a954
RS
591 printf_monitor (CMD_END);
592 }
593 expect_prompt (1);
594 }
595 return;
596}
597
598/* Store the remote registers from the contents of the block REGS. */
599
600void
601monitor_store_registers ()
602{
603 int regno;
604
605#ifdef LOG_FILE
606 fprintf (log_file, "\nIn Fetch Registers\n");
607 fflush (log_file);
608#endif
609 for (regno = 0; regno <= PC_REGNUM; regno++)
610 monitor_store_register(regno);
611
612 registers_changed ();
613}
614
f1ca4cbc
RS
615/*
616 * monitor_store_register -- store register REGNO, or all if REGNO == 0.
617 * return errno value.
618 */
51d6a954
RS
619void
620monitor_store_register (regno)
621 int regno;
622{
623 char *name;
f1ca4cbc
RS
624 int i;
625
626 i = read_register(regno);
51d6a954
RS
627
628#ifdef LOG_FILE
629 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
630#endif
631
632 if (regno < 0)
633 monitor_store_registers ();
634 else {
635 if (sr_get_debug() > 3)
636 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
637
638 name = get_reg_name (regno);
639 if (STREQ(name, ""))
640 return;
f1ca4cbc
RS
641 printf_monitor (ROMCMD(SET_REG), name, read_register(regno));
642 expect (name, 1); /* strip the leading garbage */
51d6a954
RS
643 if (*ROMDELIM(SET_REG) != 0) { /* if there's a delimiter */
644 expect (ROMDELIM(SET_REG), 1);
f1ca4cbc
RS
645 get_hex_word(1);
646 printf_monitor ("%d%s\n", i, CMD_END);
51d6a954
RS
647 }
648 expect_prompt (1);
649 }
650 return;
651
652#if 0
653 printf_monitor (SET_REG, get_reg_name (regno),
654 read_register (regno));
655 expect_prompt (1);
656 }
657#endif
658}
659
660/* Get ready to modify the registers array. On machines which store
661 individual registers, this doesn't need to do anything. On machines
662 which store all the registers in one fell swoop, this makes sure
663 that registers contains all the registers from the program being
664 debugged. */
665
666void
667monitor_prepare_to_store ()
668{
669 /* Do nothing, since we can store individual regs */
670}
671
672void
673monitor_files_info ()
674{
675 printf ("\tAttached to %s at %d baud.\n",
676 dev_name, baudrate);
677}
678
f1ca4cbc
RS
679/*
680 * monitor_write_inferior_memory -- Copy LEN bytes of data from debugger
681 * memory at MYADDR to inferior's memory at MEMADDR. Returns length moved.
682 */
51d6a954
RS
683int
684monitor_write_inferior_memory (memaddr, myaddr, len)
685 CORE_ADDR memaddr;
686 unsigned char *myaddr;
687 int len;
688{
689 int i;
690 char buf[10];
691
692#ifdef LOG_FILE
693 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
694#endif
695
f1ca4cbc
RS
696 if (sr_get_debug() > 0)
697 printf ("\nTrying to set 0x%x to 0x%x\n", memaddr, myaddr);
698
699 for (i = 0; i < len; i++) {
700 printf_monitor (ROMCMD(SET_MEM), memaddr + i, myaddr[i] );
701 if (*ROMDELIM(SET_MEM) != 0) { /* if there's a delimiter */
702 expect (ROMDELIM(SET_MEM), 1);
51d6a954
RS
703 expect (CMD_DELIM);
704 printf_monitor ("%x", myaddr[i]);
51d6a954 705 }
f1ca4cbc
RS
706/*** printf_monitor ("%x", myaddr[i]); ***/
707 if (sr_get_debug() > 1)
708 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
709 if (*ROMDELIM(SET_MEM) != 0) {
710 expect (CMD_DELIM);
711 printf_monitor (CMD_END);
712 }
713 expect_prompt (1);
714 }
51d6a954
RS
715 return len;
716}
717
718/*
719 * monitor_read_inferior_memory -- read LEN bytes from inferior memory
720 * at MEMADDR. Put the result at debugger address MYADDR. Returns
721 * length moved.
722 */
723int
724monitor_read_inferior_memory(memaddr, myaddr, len)
725 CORE_ADDR memaddr;
726 char *myaddr;
727 int len;
728{
729 int i, j;
730 char buf[20];
731
732 /* Number of bytes read so far. */
733 int count;
734
735 /* Starting address of this pass. */
736 unsigned long startaddr;
737
738 /* Number of bytes to read in this pass. */
739 int len_this_pass;
740
741#ifdef LOG_FILE
742 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
743#endif
744
745 /* Note that this code works correctly if startaddr is just less
746 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
747 thing). That is, something like
748 monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
749 works--it never adds len To memaddr and gets 0. */
750 /* However, something like
751 monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
752 doesn't need to work. Detect it and give up if there's an attempt
753 to do that. */
754 if (((memaddr - 1) + len) < memaddr) {
755 errno = EIO;
756 return 0;
757 }
758
759 startaddr = memaddr;
760 count = 0;
761 while (count < len) {
762 len_this_pass = 16;
763 if ((startaddr % 16) != 0)
764 len_this_pass -= startaddr % 16;
765 if (len_this_pass > (len - count))
766 len_this_pass = (len - count);
767 if (sr_get_debug())
768 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
769
770 for (i = 0; i < len_this_pass; i++) {
771 printf_monitor (ROMCMD(GET_MEM), startaddr, startaddr);
772 sprintf (buf, ROMCMD(GET_MEM), startaddr, startaddr);
773#if 0
774 expect (buf,1); /* get the command echo */
775 get_hex_word(1); /* strip away the address */
776#endif
777 if (*ROMDELIM(GET_MEM) != 0) { /* if there's a delimiter */
778 expect (ROMDELIM(GET_MEM), 1);
779 } else {
780 sprintf (buf, ROMCMD(GET_MEM), startaddr, startaddr);
781 expect (buf,1); /* get the command echo */
782 get_hex_word(1); /* strip away the address */
783 }
784 get_hex_byte (&myaddr[count++]); /* get the value at this address */
785
786 if (*ROMDELIM(GET_MEM) != 0) {
787 printf_monitor (CMD_END);
788 }
789 expect_prompt (1);
790 startaddr += 1;
791 }
792 }
793 return len;
794}
795
796/* FIXME-someday! merge these two. */
797int
798monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
799 CORE_ADDR memaddr;
800 char *myaddr;
801 int len;
802 int write;
803 struct target_ops *target; /* ignored */
804{
805 if (write)
806 return monitor_write_inferior_memory (memaddr, myaddr, len);
807 else
808 return monitor_read_inferior_memory (memaddr, myaddr, len);
809}
810
811void
812monitor_kill (args, from_tty)
813 char *args;
814 int from_tty;
815{
816 return; /* ignore attempts to kill target system */
817}
818
819/* Clean up when a program exits.
820 The program actually lives on in the remote processor's RAM, and may be
821 run again without a download. Don't leave it full of breakpoint
822 instructions. */
823
824void
825monitor_mourn_inferior ()
826{
827 remove_breakpoints ();
828 generic_mourn_inferior (); /* Do all the proper things now */
829}
830
831#define MAX_MONITOR_BREAKPOINTS 16
832
833extern int memory_breakpoint_size;
834static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
835
836/*
837 * monitor_insert_breakpoint -- add a breakpoint
838 */
839int
840monitor_insert_breakpoint (addr, shadow)
841 CORE_ADDR addr;
842 char *shadow;
843{
844 int i;
845
846#ifdef LOG_FILE
847 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
848#endif
849
f1ca4cbc
RS
850 if (sr_get_debug() > 4)
851 printf ("insert_breakpoint() addr = 0x%x\n", addr);
852
853 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++) {
854 if (breakaddr[i] == 0) {
855 breakaddr[i] = addr;
856 if (sr_get_debug() > 4)
857 printf ("Breakpoint at %x\n", addr);
858 monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
859 printf_monitor(SET_BREAK_CMD, addr);
860 expect_prompt(1);
861 return 0;
862 }
863 }
864
51d6a954
RS
865 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
866 return 1;
867}
868
869/*
870 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
871 */
872int
873monitor_remove_breakpoint (addr, shadow)
874 CORE_ADDR addr;
875 char *shadow;
876{
877 int i;
878
879#ifdef LOG_FILE
880 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
881#endif
882 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
883 if (breakaddr[i] == addr)
884 {
885 breakaddr[i] = 0;
886 /* some monitors remove breakpoints based on the address */
887 if (strcasecmp (target_shortname, "bug") == 0)
888 printf_monitor(CLR_BREAK_CMD, addr);
889 else
890 printf_monitor(CLR_BREAK_CMD, i);
891 expect_prompt(1);
892 return 0;
893 }
894
895 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
896 return 1;
897}
898
899/* Load a file. This is usually an srecord, which is ascii. No
900 protocol, just sent line by line. */
901
902#define DOWNLOAD_LINE_SIZE 100
903void
904monitor_load (arg)
905 char *arg;
906{
907 FILE *download;
908 char buf[DOWNLOAD_LINE_SIZE];
909 int i, bytes_read;
910
911 if (sr_get_debug())
912 printf ("Loading %s to monitor\n", arg);
913
914 download = fopen (arg, "r");
915 if (download == NULL)
916 {
917 error (sprintf (buf, "%s Does not exist", arg));
918 return;
919 }
920
921 printf_monitor (LOAD_CMD);
922/* expect ("Waiting for S-records from host... ", 1); */
923
924 while (!feof (download))
925 {
926 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
927 if (hashmark)
928 {
929 putchar ('.');
930 fflush (stdout);
931 }
932
933 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
934 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
935 break;
936 }
937 i = 0;
938 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
939 if (bytes_read < DOWNLOAD_LINE_SIZE)
940 {
941 if (!feof (download))
942 error ("Only read %d bytes\n", bytes_read);
943 break;
944 }
945 }
946
947 if (hashmark)
948 {
949 putchar ('\n');
950 }
951 if (!feof (download))
952 error ("Never got EOF while downloading");
953 fclose (download);
954}
955
956/* Put a command string, in args, out to MONITOR. Output from MONITOR is placed
957 on the users terminal until the prompt is seen. */
958
959void
960monitor_command (args, fromtty)
961 char *args;
962 int fromtty;
963{
964#ifdef LOG_FILE
965 fprintf (log_file, "\nIn command (args=%s)\n", args);
966#endif
967 if (monitor_desc == NULL)
968 error("monitor target not open.");
969
970 if (!args)
971 error("Missing command.");
972
973 printf_monitor("%s\r", args);
974 expect_prompt(0);
975}
976
977/*
978 * _initialize_remote_monitors -- setup a few addtitional commands that
979 * are usually only used by monitors.
980 */
981void
982_initialize_remote_monitors ()
983{
984 struct cmd_list_element *c;
985
986 /* this sets the type of download protocol */
987 c = add_set_cmd ("loadtype", no_class, var_string, (char *)&loadtype_str,
988 "Set the type of the remote load protocol.\n", &setlist);
989 c->function.sfunc = set_loadtype_command;
990 add_show_from_set (c, &showlist);
991 loadtype_str = savestring ("generic", 8);
992
993 add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
994 (char *)&hashmark,
995 "Set display of activity while downloading a file.\n\
996When enabled, a period \'.\' is displayed.",
997 &setlist),
998 &showlist);
999
1000 /* generic monitor command */
1001 add_com ("monitor", class_obscure, monitor_command,
1002 "Send a command to the debug monitor.");
1003}
This page took 0.06077 seconds and 4 git commands to generate.