]> Git Repo - binutils.git/blob - gdb/monitor.c
Memory_reads_inferior() and monitor_fetch_registers() now work good on
[binutils.git] / gdb / monitor.c
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
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 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
51 struct monitor_ops *current_monitor;
52 extern struct cmd_list_element *setlist;
53 extern struct cmd_list_element *unsetlist;
54 struct cmd_list_element *showlist;
55
56 static 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)
61 FILE *log_file;
62 #endif
63
64 static 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    */
69 static serial_t monitor_desc = NULL;
70
71 /* sets the download protocol, choices are srec, generic, boot */
72 char *loadtype;
73 static char *loadtype_str;
74 static 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  */
80 static void
81 set_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  */
109 static void
110 printf_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.  */
133 static int
134 readchar(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.  */
166 static void
167 expect (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.  */
215 static void
216 expect_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  */
230 static int
231 junk(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  */
254 static int
255 get_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  */
284 static void
285 get_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  */
307 static int
308 get_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.  */
325 void
326 monitor_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
369 static int baudrate = 9600;
370 static char dev_name[100];
371
372 void
373 monitor_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
427 void
428 monitor_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.  */
447 void
448 monitor_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  */
459 void
460 monitor_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
487 int
488 monitor_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
516 static char *
517 get_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
537   return buf;
538 }
539
540 /* read the remote registers into the block regs.  */
541
542 void
543 monitor_fetch_registers ()
544 {
545   int regno;
546
547   /* yeah yeah, i know this is horribly inefficient.  but it isn't done
548      very often...  i'll clean it up later.  */
549
550   for (regno = 0; regno <= PC_REGNUM; regno++)
551     monitor_fetch_register(regno);
552 }
553
554 /* 
555  * monitor_fetch_register -- fetch register REGNO, or all registers if REGNO is -1.
556  *  Returns errno value.
557  */
558 void
559 monitor_fetch_register (regno)
560      int regno;
561 {
562   int val, j;
563
564 #ifdef LOG_FILE
565   fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
566   fflush (log_file);
567 #endif
568
569   if (regno < 0) {
570     monitor_fetch_registers ();
571   } else {
572     char *name = get_reg_name (regno);
573     if (STREQ(name, ""))
574       return;
575     printf_monitor (ROMCMD(GET_REG), name);     /* send the command */
576     expect (name, 1);                           /* then strip the leading garbage */
577     if (*ROMDELIM(GET_REG) != 0) {              /* if there's a delimiter */
578       expect (ROMDELIM(GET_REG), 1);
579     }
580     
581     val =  get_hex_word();                      /* get the value, ignore junk */
582     supply_register (regno, (char *) &val);
583     
584     if (*ROMDELIM(GET_REG) != 0) {
585 /***      expect (ROMRES(GET_REG)); ***/
586       printf_monitor (CMD_END);
587     }
588     expect_prompt (1);
589   }
590   return;
591 }
592
593 /* Store the remote registers from the contents of the block REGS.  */
594
595 void
596 monitor_store_registers ()
597 {
598   int regno;
599
600 #ifdef LOG_FILE
601   fprintf (log_file, "\nIn Fetch Registers\n");
602   fflush (log_file);
603 #endif
604   for (regno = 0; regno <= PC_REGNUM; regno++)
605     monitor_store_register(regno);
606
607   registers_changed ();
608 }
609
610 /* Store register REGNO, or all if REGNO == 0.
611    return errno value.  */
612 void
613 monitor_store_register (regno)
614      int regno;
615 {
616   char *name;
617
618 #ifdef LOG_FILE
619   fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
620 #endif
621
622   if (regno < 0)
623     monitor_store_registers ();
624   else {
625     if (sr_get_debug() > 3)
626       printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
627     
628     name = get_reg_name (regno);
629     if (STREQ(name, ""))
630       return;
631     printf_monitor (ROMCMD(SET_REG), name);     /* send the command */
632     expect (name, 1);                           /* then strip the leading garbage */
633     if (*ROMDELIM(SET_REG) != 0) {              /* if there's a delimiter */
634       expect (ROMDELIM(SET_REG), 1);
635     }
636     
637     if (*ROMDELIM(SET_REG) != 0) {
638       printf_monitor ("%s%s\n",read_register(regno), CMD_END);
639     }
640     expect_prompt (1);
641   }
642   return;
643   
644 #if 0
645       printf_monitor (SET_REG, get_reg_name (regno),
646                       read_register (regno));
647       expect_prompt (1);
648     }
649 #endif
650 }
651
652 /* Get ready to modify the registers array.  On machines which store
653    individual registers, this doesn't need to do anything.  On machines
654    which store all the registers in one fell swoop, this makes sure
655    that registers contains all the registers from the program being
656    debugged.  */
657
658 void
659 monitor_prepare_to_store ()
660 {
661   /* Do nothing, since we can store individual regs */
662 }
663
664 void
665 monitor_files_info ()
666 {
667   printf ("\tAttached to %s at %d baud.\n",
668           dev_name, baudrate);
669 }
670
671 /* Copy LEN bytes of data from debugger memory at MYADDR
672    to inferior's memory at MEMADDR.  Returns length moved.  */
673 int
674 monitor_write_inferior_memory (memaddr, myaddr, len)
675      CORE_ADDR memaddr;
676      unsigned char *myaddr;
677      int len;
678 {
679   int i;
680   char buf[10];
681
682 #ifdef LOG_FILE
683   fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
684 #endif
685
686 #define MEM_PROMPT ""                           /* FIXME, bogus */
687   for (i = 0; i < len; i++)
688     {
689       printf_monitor (SET_MEM, memaddr + i);
690       expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1); 
691       expect (CMD_DELIM);
692       printf_monitor ("%x", myaddr[i]);
693       if (sr_get_debug())
694         printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
695       if (CMD_END)
696         {
697 /***      expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);          
698           expect (CMD_DELIM); ***/
699           printf_monitor (CMD_END);
700         }
701       expect_prompt (1);
702     }
703   return len;
704 }
705
706 /*
707  * monitor_read_inferior_memory -- read LEN bytes from inferior memory
708  *      at MEMADDR.  Put the result at debugger address MYADDR.  Returns
709  *      length moved.
710  */
711 int
712 monitor_read_inferior_memory(memaddr, myaddr, len)
713      CORE_ADDR memaddr;
714      char *myaddr;
715      int len;
716 {
717   int i, j;
718   char buf[20];
719
720   /* Number of bytes read so far.  */
721   int count;
722
723   /* Starting address of this pass.  */
724   unsigned long startaddr;
725
726   /* Number of bytes to read in this pass.  */
727   int len_this_pass;
728
729 #ifdef LOG_FILE
730   fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
731 #endif
732
733   /* Note that this code works correctly if startaddr is just less
734      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
735      thing).  That is, something like
736      monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
737      works--it never adds len To memaddr and gets 0.  */
738   /* However, something like
739      monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
740      doesn't need to work.  Detect it and give up if there's an attempt
741      to do that.  */
742   if (((memaddr - 1) + len) < memaddr) {
743     errno = EIO;
744     return 0;
745   }
746   
747   startaddr = memaddr;
748   count = 0;
749   while (count < len) {
750     len_this_pass = 16;
751     if ((startaddr % 16) != 0)
752       len_this_pass -= startaddr % 16;
753     if (len_this_pass > (len - count))
754       len_this_pass = (len - count);
755     if (sr_get_debug())
756       printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
757     
758     for (i = 0; i < len_this_pass; i++) {
759       printf_monitor (ROMCMD(GET_MEM), startaddr, startaddr);
760       sprintf (buf, ROMCMD(GET_MEM), startaddr, startaddr);
761 #if 0
762       expect (buf,1);                           /* get the command echo */
763       get_hex_word(1);                          /* strip away the address */
764 #endif
765       if (*ROMDELIM(GET_MEM) != 0) {            /* if there's a delimiter */
766         expect (ROMDELIM(GET_MEM), 1);
767       } else {
768         sprintf (buf, ROMCMD(GET_MEM), startaddr, startaddr);
769         expect (buf,1);                         /* get the command echo */
770         get_hex_word(1);                        /* strip away the address */
771       }
772       get_hex_byte (&myaddr[count++]);          /* get the value at this address */
773
774       if (*ROMDELIM(GET_MEM) != 0) {
775         printf_monitor (CMD_END);
776       }
777       expect_prompt (1);
778       startaddr += 1;
779     }
780   }
781   return len;
782 }
783
784 /* FIXME-someday!  merge these two.  */
785 int
786 monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
787      CORE_ADDR memaddr;
788      char *myaddr;
789      int len;
790      int write;
791      struct target_ops *target;         /* ignored */
792 {
793   if (write)
794     return monitor_write_inferior_memory (memaddr, myaddr, len);
795   else
796     return monitor_read_inferior_memory (memaddr, myaddr, len);
797 }
798
799 void
800 monitor_kill (args, from_tty)
801      char *args;
802      int from_tty;
803 {
804   return;               /* ignore attempts to kill target system */
805 }
806
807 /* Clean up when a program exits.
808    The program actually lives on in the remote processor's RAM, and may be
809    run again without a download.  Don't leave it full of breakpoint
810    instructions.  */
811
812 void
813 monitor_mourn_inferior ()
814 {
815   remove_breakpoints ();
816   generic_mourn_inferior ();    /* Do all the proper things now */
817 }
818
819 #define MAX_MONITOR_BREAKPOINTS 16
820
821 extern int memory_breakpoint_size;
822 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
823
824 /*
825  * monitor_insert_breakpoint -- add a breakpoint
826  */
827 int
828 monitor_insert_breakpoint (addr, shadow)
829      CORE_ADDR addr;
830      char *shadow;
831 {
832   int i;
833
834 #ifdef LOG_FILE
835   fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
836 #endif
837
838   for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
839     if (breakaddr[i] == 0)
840       {
841         breakaddr[i] = addr;
842         if (sr_get_debug())
843           printf ("Breakpoint at %x\n", addr);
844         monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
845         printf_monitor(SET_BREAK_CMD, addr);
846         expect_prompt(1);
847         return 0;
848       }
849   
850   fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
851   return 1;
852 }
853
854 /*
855  * _remove_breakpoint -- Tell the monitor to remove a breakpoint
856  */
857 int
858 monitor_remove_breakpoint (addr, shadow)
859      CORE_ADDR addr;
860      char *shadow;
861 {
862   int i;
863
864 #ifdef LOG_FILE
865   fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
866 #endif
867   for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
868     if (breakaddr[i] == addr)
869       {
870         breakaddr[i] = 0;
871         /* some monitors remove breakpoints based on the address */
872         if (strcasecmp (target_shortname, "bug") == 0)   
873             printf_monitor(CLR_BREAK_CMD, addr);
874           else
875             printf_monitor(CLR_BREAK_CMD, i);
876         expect_prompt(1);
877         return 0;
878       }
879
880   fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
881   return 1;
882 }
883
884 /* Load a file. This is usually an srecord, which is ascii. No 
885    protocol, just sent line by line. */
886
887 #define DOWNLOAD_LINE_SIZE 100
888 void
889 monitor_load (arg)
890     char        *arg;
891 {
892   FILE *download;
893   char buf[DOWNLOAD_LINE_SIZE];
894   int i, bytes_read;
895
896   if (sr_get_debug())
897     printf ("Loading %s to monitor\n", arg);
898
899   download = fopen (arg, "r");
900   if (download == NULL)
901     {
902     error (sprintf (buf, "%s Does not exist", arg));
903     return;
904   }
905
906   printf_monitor (LOAD_CMD);
907 /*  expect ("Waiting for S-records from host... ", 1); */
908
909   while (!feof (download))
910     {
911       bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
912       if (hashmark)
913         {
914           putchar ('.');
915           fflush (stdout);
916         }
917
918       if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
919         fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
920         break;
921       }
922       i = 0;
923       while (i++ <=200000) {} ;                         /* Ugly HACK, probably needs flow control */
924       if (bytes_read < DOWNLOAD_LINE_SIZE)
925         {
926           if (!feof (download))
927             error ("Only read %d bytes\n", bytes_read);
928           break;
929         }
930     }
931
932   if (hashmark)
933     {
934       putchar ('\n');
935     }
936   if (!feof (download))
937     error ("Never got EOF while downloading");
938   fclose (download);
939 }
940
941 /* Put a command string, in args, out to MONITOR.  Output from MONITOR is placed
942    on the users terminal until the prompt is seen. */
943
944 void
945 monitor_command (args, fromtty)
946      char       *args;
947      int        fromtty;
948 {
949 #ifdef LOG_FILE
950   fprintf (log_file, "\nIn command (args=%s)\n", args);
951 #endif
952   if (monitor_desc == NULL)
953     error("monitor target not open.");
954   
955   if (!args)
956     error("Missing command.");
957         
958   printf_monitor("%s\r", args);
959   expect_prompt(0);
960 }
961
962 /*
963  * _initialize_remote_monitors -- setup a few addtitional commands that
964  *              are usually only used by monitors.
965  */
966 void
967 _initialize_remote_monitors ()
968 {
969   struct cmd_list_element *c;
970
971   /* this sets the type of download protocol */
972   c = add_set_cmd ("loadtype", no_class, var_string, (char *)&loadtype_str,
973        "Set the type of the remote load protocol.\n", &setlist);
974   c->function.sfunc =  set_loadtype_command;
975   add_show_from_set (c, &showlist);
976   loadtype_str = savestring ("generic", 8);
977
978   add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
979                                   (char *)&hashmark,
980                                   "Set display of activity while downloading a file.\n\
981 When enabled, a period \'.\' is displayed.",
982                                   &setlist),
983                      &showlist);
984
985   /* generic monitor command */
986   add_com ("monitor", class_obscure, monitor_command,
987            "Send a command to the debug monitor."); 
988 }
This page took 0.081294 seconds and 4 git commands to generate.