]> Git Repo - binutils.git/blob - gdb/remote-mon.c
The following fixes a FAIL caused by the fact that the alpha stabs
[binutils.git] / gdb / remote-mon.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 remote-eb.c, which did a similar job, but for
22    an AMD-29K running EBMON.  That file was in turn derived from remote.c
23    as mentioned in the following comment (left in for comic relief):
24
25   "This is like remote.c but is for an esoteric situation--
26    having an a29k board in a PC hooked up to a unix machine with
27    a serial line, and running ctty com1 on the PC, through which
28    the unix machine can run ebmon.  Not to mention that the PC
29    has PC/NFS, so it can access the same executables that gdb can,
30    over the net in real time."
31
32    In reality, this module talks to a debug monitor called 'MONITOR', which
33    We communicate with MONITOR via either a direct serial line, or a TCP
34    (or possibly TELNET) stream to a terminal multiplexor,
35    which in turn talks to the target board.
36
37    This is based on remote-st2000.c. I left in the above note here for histerical
38    reasons.
39 */
40
41 #include "defs.h"
42 #include "gdbcore.h"
43 #include "target.h"
44 #include "wait.h"
45 #include <varargs.h>
46 #include <signal.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include "command.h"
50 #include "serial.h"
51 #include "monitor.h"
52 #include "remote-utils.h"
53
54 #ifdef HAVE_TERMIO
55 #  define TERMINAL struct termios
56 #else
57 #  define TERMINAL struct sgttyb
58 #endif
59
60 struct monitor_ops *current_monitor;
61 extern struct target_ops rom68k_ops;            /* Forward declaration */
62 extern struct target_ops mon68_ops;             /* Forward declaration */
63 extern struct target_ops monitor_bug_ops;       /* Forward declaration */
64 extern struct monitor_ops rom68k_cmds;          /* Forward declaration */
65 #if 0
66 extern struct monitor_ops mon68_cmds;           /* Forward declaration */
67 #endif
68 extern struct monitor_ops bug_cmds;             /* Forward declaration */
69 extern struct cmd_list_element *setlist;
70 extern struct cmd_list_element *unsetlist;
71 struct cmd_list_element *showlist;
72
73 static void monitor_close();
74 static void monitor_fetch_register();
75 static void monitor_store_register();
76 #if 0
77 static int sr_get_debug();                      /* flag set by "set remotedebug" */
78 #endif
79 static int hashmark;                            /* flag set by "set hash" */
80
81 /* FIXME: Replace with sr_get_debug ().  */
82 #define LOG_FILE "monitor.log"
83 #if defined (LOG_FILE)
84 FILE *log_file;
85 #endif
86
87 static int timeout = 24;
88
89 /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
90    monitor_open knows that we don't have a file open when the program starts.
91    */
92 static serial_t monitor_desc = NULL;
93
94 /* Send data to monitor.  Works just like printf. */
95
96 static void
97 printf_monitor(va_alist)
98      va_dcl
99 {
100   va_list args;
101   char *pattern;
102   char buf[200];
103   int i;
104
105   va_start(args);
106
107   pattern = va_arg(args, char *);
108
109   vsprintf(buf, pattern, args);
110
111   if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
112     fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
113 }
114
115 /* Read a character from the remote system, doing all the fancy
116    timeout stuff.  */
117 static int
118 readchar(timeout)
119      int timeout;
120 {
121   int c;
122
123   c = SERIAL_READCHAR(monitor_desc, timeout);
124
125   if (sr_get_debug())
126     putchar(c & 0x7f);
127
128 #ifdef LOG_FILE
129   if (isascii (c))
130     putc(c & 0x7f, log_file);
131 #endif
132
133   if (c >= 0)
134     return c & 0x7f;
135
136   if (c == SERIAL_TIMEOUT)
137     {
138       if (timeout == 0)
139         return c;               /* Polls shouldn't generate timeout errors */
140
141       error("Timeout reading from remote system.");
142     }
143
144   perror_with_name("remote-monitor");
145 }
146
147 /* Scan input from the remote system, until STRING is found.  If DISCARD is
148    non-zero, then discard non-matching input, else print it out.
149    Let the user break out immediately.  */
150 static void
151 expect(string, discard)
152      char *string;
153      int discard;
154 {
155   char *p = string;
156   int c;
157
158   if (sr_get_debug())
159     printf ("Expecting \"%s\"\n", string);
160
161   immediate_quit = 1;
162   while (1)
163     {
164       c = readchar(timeout);
165       if (!isascii (c))
166         continue;
167       if (c == *p++)
168         {
169           if (*p == '\0')
170             {
171               immediate_quit = 0;
172               if (sr_get_debug())
173                 printf ("\nMatched\n");
174               return;
175             }
176         }
177       else
178         {
179           if (!discard)
180             {
181               fwrite(string, 1, (p - 1) - string, stdout);
182               putchar((char)c);
183               fflush(stdout);
184             }
185           p = string;
186         }
187     }
188 }
189
190 /* Keep discarding input until we see the MONITOR prompt.
191
192    The convention for dealing with the prompt is that you
193    o give your command
194    o *then* wait for the prompt.
195
196    Thus the last thing that a procedure does with the serial line
197    will be an expect_prompt().  Exception:  monitor_resume does not
198    wait for the prompt, because the terminal is being handed over
199    to the inferior.  However, the next thing which happens after that
200    is a monitor_wait which does wait for the prompt.
201    Note that this includes abnormal exit, e.g. error().  This is
202    necessary to prevent getting into states from which we can't
203    recover.  */
204 static void
205 expect_prompt(discard)
206      int discard;
207 {
208 #if defined (LOG_FILE)
209   /* This is a convenient place to do this.  The idea is to do it often
210      enough that we never lose much data if we terminate abnormally.  */
211   fflush(log_file);
212 #endif
213   expect (PROMPT, discard);
214 }
215
216 /* Get a hex digit from the remote system & return its value.
217    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
218 static int
219 get_hex_digit(ignore_space)
220      int ignore_space;
221 {
222   int ch;
223   while (1)
224     {
225       ch = readchar(timeout);
226       if (ch >= '0' && ch <= '9')
227         return ch - '0';
228       else if (ch >= 'A' && ch <= 'F')
229         return ch - 'A' + 10;
230       else if (ch >= 'a' && ch <= 'f')
231         return ch - 'a' + 10;
232       else if (ch == ' ' && ignore_space)
233         ;
234       else
235         {
236           expect_prompt(1);
237           error("Invalid hex digit from remote system.");
238         }
239     }
240 }
241
242 /* Get a byte from monitor and put it in *BYT.  Accept any number
243    leading spaces.  */
244 static void
245 get_hex_byte (byt)
246      char *byt;
247 {
248   int val;
249
250   val = get_hex_digit (1) << 4;
251   val |= get_hex_digit (0);
252   *byt = val;
253 }
254
255 /* Get N 32-bit words from remote, each preceded by a space,
256    and put them in registers starting at REGNO.  */
257 static void
258 get_hex_regs (n, regno)
259      int n;
260      int regno;
261 {
262   long val;
263   int i;
264
265   for (i = 0; i < n; i++)
266     {
267       int j;
268       
269       val = 0;
270       for (j = 0; j < 8; j++)
271         val = (val << 4) + get_hex_digit (j == 0);
272       supply_register (regno++, (char *) &val);
273     }
274 }
275
276 /* This is called not only when we first attach, but also when the
277    user types "run" after having attached.  */
278 static void
279 monitor_create_inferior (execfile, args, env)
280      char *execfile;
281      char *args;
282      char **env;
283 {
284   int entry_pt;
285
286   if (args && *args)
287     error("Can't pass arguments to remote MONITOR process");
288
289   if (execfile == 0 || exec_bfd == 0)
290     error("No exec file specified");
291
292   entry_pt = (int) bfd_get_start_address (exec_bfd);
293
294 #ifdef LOG_FILE
295   fputs ("\nIn Create_inferior()", log_file);
296 #endif
297
298 /* The "process" (board) is already stopped awaiting our commands, and
299    the program is already downloaded.  We just set its PC and go.  */
300
301   clear_proceed_status ();
302
303   /* Tell wait_for_inferior that we've started a new process.  */
304   init_wait_for_inferior ();
305
306   /* Set up the "saved terminal modes" of the inferior
307      based on what modes we are starting it with.  */
308   target_terminal_init ();
309
310   /* Install inferior's terminal modes.  */
311   target_terminal_inferior ();
312
313   /* insert_step_breakpoint ();  FIXME, do we need this?  */
314
315   /* Let 'er rip... */
316   proceed ((CORE_ADDR)entry_pt, TARGET_SIGNAL_DEFAULT, 0);
317 }
318
319 /* Open a connection to a remote debugger.
320    NAME is the filename used for communication.  */
321
322 static int baudrate = 9600;
323 static char dev_name[100];
324
325 static void
326 general_open(args, name, from_tty)
327      char *args;
328      char *name;
329      int from_tty;
330 {
331   if (args == NULL)
332     error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
333 `target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
334
335   target_preopen(from_tty);
336
337 /*  if (is_open) */
338     monitor_close(0);
339
340   strcpy(dev_name, args);
341   monitor_desc = SERIAL_OPEN(dev_name);
342
343   if (monitor_desc == NULL)
344     perror_with_name(dev_name);
345
346   if (baud_rate != -1)
347     {
348       if (SERIAL_SETBAUDRATE (monitor_desc, baud_rate))
349         {
350           SERIAL_CLOSE (monitor_desc);
351           perror_with_name (name);
352         }
353     }
354
355   SERIAL_RAW(monitor_desc);
356
357 #if defined (LOG_FILE)
358   log_file = fopen (LOG_FILE, "w");
359   if (log_file == NULL)
360     perror_with_name (LOG_FILE);
361 #endif
362
363   /* Hello?  Are you there?  */
364   printf_monitor("\r"); /* CR wakes up monitor */
365   
366   expect_prompt(1);
367
368   if (from_tty)
369     printf("Remote %s connected to %s\n", target_shortname,
370            dev_name);
371 }
372
373 static void
374 rom68k_open(args, from_tty)
375      char *args;
376      int from_tty;
377 {
378   push_target(&rom68k_ops);
379   push_monitor (&rom68k_cmds);
380
381   general_open (args, "rom68k", from_tty);
382 }
383
384 static void
385 mon68_open(args, from_tty)
386      char *args;
387      int from_tty;
388 {
389   push_target(&mon68_ops);
390 #if 0
391   push_monitor (&mon68_cmds);
392 #endif
393
394   general_open (args, "mon68", from_tty);
395 }
396
397 static void
398 bug_open(args, from_tty)
399      char *args;
400      int from_tty;
401 {
402   push_target(&monitor_bug_ops);
403   push_monitor (&bug_cmds);
404
405   general_open (args, "bug", from_tty);
406 }
407
408 /*
409  * _close -- Close out all files and local state before this target loses control.
410  */
411
412 static void
413 monitor_close (quitting)
414      int quitting;
415 {
416   SERIAL_CLOSE(monitor_desc);
417   monitor_desc = NULL;
418
419 #if defined (LOG_FILE)
420   if (log_file) {
421     if (ferror(log_file))
422       fprintf(stderr, "Error writing log file.\n");
423     if (fclose(log_file) != 0)
424       fprintf(stderr, "Error closing log file.\n");
425   }
426 #endif
427 }
428
429 /* Terminate the open connection to the remote debugger.
430    Use this when you want to detach and do something else
431    with your gdb.  */
432 static void
433 monitor_detach (from_tty)
434      int from_tty;
435 {
436   pop_target();         /* calls monitor_close to do the real work */
437   if (from_tty)
438     printf ("Ending remote %s debugging\n", target_shortname);
439 }
440  
441 /*
442  * _resume -- Tell the remote machine to resume.
443  */
444 static void
445 monitor_resume (pid, step, sig)
446      int pid, step;
447      enum target_signal sig;
448 {
449 #ifdef LOG_FILE
450   fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
451 #endif
452
453   if (step)
454     {
455       printf_monitor (STEP_CMD);
456       /* wait for the echo.  */
457       expect (STEP_CMD, 1);
458     }
459   else
460     {
461       printf_monitor (GO_CMD);
462       /* swallow the echo.  */
463       expect (GO_CMD, 1);
464     }
465 }
466
467 /*
468  * _wait -- Wait until the remote machine stops, then return,
469  *          storing status in status just as `wait' would.
470  */
471
472 static int
473 monitor_wait (pid, status)
474      int pid;
475      struct target_waitstatus *status;
476 {
477   int old_timeout = timeout;
478 #ifdef LOG_FILE
479   fputs ("\nIn wait ()", log_file);
480 #endif
481
482   status->kind = TARGET_WAITKIND_EXITED;
483   status->value.integer = 0;
484
485   timeout = 0;          /* Don't time out -- user program is running. */
486
487   expect_prompt(0);    /* Wait for prompt, outputting extraneous text */
488
489   status->kind = TARGET_WAITKIND_STOPPED;
490   status->value.sig = TARGET_SIGNAL_TRAP;
491
492   timeout = old_timeout;
493
494   return 0;
495 }
496
497 /* Return the name of register number regno in the form input and output by
498    monitor.  Currently, register_names just happens to contain exactly what
499    monitor wants.  Lets take advantage of that just as long as possible! */
500
501 static char *
502 get_reg_name (regno)
503      int regno;
504 {
505   static char buf[50];
506   const char *p;
507   char *b;
508
509   b = buf;
510
511   if (regno < 0)
512     return ("");
513   for (p = reg_names[regno]; *p; p++)
514     *b++ = toupper(*p);
515   *b = '\000';
516
517   return buf;
518 }
519
520 /* read the remote registers into the block regs.  */
521
522 static void
523 monitor_fetch_registers ()
524 {
525   int regno;
526
527   /* yeah yeah, i know this is horribly inefficient.  but it isn't done
528      very often...  i'll clean it up later.  */
529
530   for (regno = 0; regno <= PC_REGNUM; regno++)
531     monitor_fetch_register(regno);
532 }
533
534 /* Fetch register REGNO, or all registers if REGNO is -1.
535    Returns errno value.  */
536 static void
537 monitor_fetch_register (regno)
538      int regno;
539 {
540   int val, j;
541
542 #ifdef LOG_FILE
543   fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
544   fflush (log_file);
545 #endif
546
547   if (regno < 0)
548     {
549       monitor_fetch_registers ();
550     }
551   else
552     {
553       char *name = get_reg_name (regno);
554       printf_monitor (GET_REG, name);
555       expect (name, 1);
556       expect (REG_DELIM, 1);
557       if (strcasecmp (name, "SR") == 0)
558         {
559           val = 0;
560           for (j = 0; j < 4; j++)
561             val = (val << 4) + get_hex_digit (j == 0);
562           supply_register (regno, (char *) &val);
563         }
564       else
565         {
566           get_hex_regs (1, regno);
567         }
568       if (CMD_END) 
569         {
570           expect (CMD_DELIM);
571           printf_monitor (CMD_END);
572         }
573       expect_prompt (1);
574     }
575   return;
576 }
577
578 /* Store the remote registers from the contents of the block REGS.  */
579
580 static void
581 monitor_store_registers ()
582 {
583   int regno;
584
585   for (regno = 0; regno <= PC_REGNUM; regno++)
586     monitor_store_register(regno);
587
588   registers_changed ();
589 }
590
591 /* Store register REGNO, or all if REGNO == 0.
592    return errno value.  */
593 static void
594 monitor_store_register (regno)
595      int regno;
596 {
597 #ifdef LOG_FILE
598   fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
599 #endif
600   if (regno == -1)
601     monitor_store_registers ();
602   else
603     {
604       if (sr_get_debug())
605         printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
606
607       printf_monitor (SET_REG, get_reg_name (regno),
608                       read_register (regno));
609
610       expect_prompt (1);
611     }
612 }
613
614 /* Get ready to modify the registers array.  On machines which store
615    individual registers, this doesn't need to do anything.  On machines
616    which store all the registers in one fell swoop, this makes sure
617    that registers contains all the registers from the program being
618    debugged.  */
619
620 static void
621 monitor_prepare_to_store ()
622 {
623   /* Do nothing, since we can store individual regs */
624 }
625
626 static void
627 monitor_files_info ()
628 {
629   printf ("\tAttached to %s at %d baud.\n",
630           dev_name, baudrate);
631 }
632
633 /* Copy LEN bytes of data from debugger memory at MYADDR
634    to inferior's memory at MEMADDR.  Returns length moved.  */
635 static int
636 monitor_write_inferior_memory (memaddr, myaddr, len)
637      CORE_ADDR memaddr;
638      unsigned char *myaddr;
639      int len;
640 {
641   int i;
642   char buf[10];
643
644 #ifdef LOG_FILE
645   fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
646 #endif
647   for (i = 0; i < len; i++)
648     {
649       printf_monitor (MEM_SET_CMD, memaddr + i);
650       expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1); 
651       expect (CMD_DELIM);
652       printf_monitor ("%x", myaddr[i]);
653       if (sr_get_debug())
654         printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
655       if (CMD_END)
656         {
657 /***      expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);          
658           expect (CMD_DELIM); ***/
659           printf_monitor (CMD_END);
660         }
661       expect_prompt (1);
662     }
663   return len;
664 }
665
666 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
667    at debugger address MYADDR.  Returns length moved.  */
668 static int
669 monitor_read_inferior_memory(memaddr, myaddr, len)
670      CORE_ADDR memaddr;
671      char *myaddr;
672      int len;
673 {
674   int i, j;
675   char buf[20];
676
677   /* Number of bytes read so far.  */
678   int count;
679
680   /* Starting address of this pass.  */
681   unsigned long startaddr;
682
683   /* Number of bytes to read in this pass.  */
684   int len_this_pass;
685
686 #ifdef LOG_FILE
687   fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
688 #endif
689
690   /* Note that this code works correctly if startaddr is just less
691      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
692      thing).  That is, something like
693      monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
694      works--it never adds len To memaddr and gets 0.  */
695   /* However, something like
696      monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
697      doesn't need to work.  Detect it and give up if there's an attempt
698      to do that.  */
699   if (((memaddr - 1) + len) < memaddr) {
700     errno = EIO;
701     return 0;
702   }
703   
704   startaddr = memaddr;
705   count = 0;
706   while (count < len)
707     {
708       len_this_pass = 16;
709       if ((startaddr % 16) != 0)
710         len_this_pass -= startaddr % 16;
711       if (len_this_pass > (len - count))
712         len_this_pass = (len - count);
713       if (sr_get_debug())
714         printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
715
716       for (i = 0; i < len_this_pass; i++)
717         {
718           printf_monitor (MEM_DIS_CMD, startaddr);
719           expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
720           get_hex_byte (&myaddr[count++]);
721           if (sr_get_debug())
722             printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
723           if (CMD_END) 
724             {
725               expect (CMD_DELIM);
726               printf_monitor (CMD_END);
727             }
728           expect_prompt (1);
729           startaddr += 1;
730         }
731     }
732   return len;
733 }
734
735 /* FIXME-someday!  merge these two.  */
736 static int
737 monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
738      CORE_ADDR memaddr;
739      char *myaddr;
740      int len;
741      int write;
742      struct target_ops *target;         /* ignored */
743 {
744   if (write)
745     return monitor_write_inferior_memory (memaddr, myaddr, len);
746   else
747     return monitor_read_inferior_memory (memaddr, myaddr, len);
748 }
749
750 static void
751 monitor_kill (args, from_tty)
752      char *args;
753      int from_tty;
754 {
755   return;               /* ignore attempts to kill target system */
756 }
757
758 /* Clean up when a program exits.
759    The program actually lives on in the remote processor's RAM, and may be
760    run again without a download.  Don't leave it full of breakpoint
761    instructions.  */
762
763 static void
764 monitor_mourn_inferior ()
765 {
766   remove_breakpoints ();
767   generic_mourn_inferior ();    /* Do all the proper things now */
768 }
769
770 #define MAX_MONITOR_BREAKPOINTS 16
771
772 extern int memory_breakpoint_size;
773 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
774
775 static int
776 monitor_insert_breakpoint (addr, shadow)
777      CORE_ADDR addr;
778      char *shadow;
779 {
780   int i;
781
782 #ifdef LOG_FILE
783   fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
784 #endif
785   for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
786     if (breakaddr[i] == 0)
787       {
788         breakaddr[i] = addr;
789         if (sr_get_debug())
790           printf ("Breakpoint at %x\n", addr);
791         monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
792         printf_monitor(SET_BREAK_CMD, addr);
793         expect_prompt(1);
794         return 0;
795       }
796
797   fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
798   return 1;
799 }
800
801 /*
802  * _remove_breakpoint -- Tell the monitor to remove a breakpoint
803  */
804 static int
805 monitor_remove_breakpoint (addr, shadow)
806      CORE_ADDR addr;
807      char *shadow;
808 {
809   int i;
810
811 #ifdef LOG_FILE
812   fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
813 #endif
814   for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
815     if (breakaddr[i] == addr)
816       {
817         breakaddr[i] = 0;
818         /* some monitors remove breakpoints based on the address */
819         if (strcasecmp (target_shortname, "bug") == 0)   
820             printf_monitor(CLR_BREAK_CMD, addr);
821           else
822             printf_monitor(CLR_BREAK_CMD, i);
823         expect_prompt(1);
824         return 0;
825       }
826
827   fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
828   return 1;
829 }
830
831 /* Load a file. This is usually an srecord, which is ascii. No 
832    protocol, just sent line by line. */
833
834 #define DOWNLOAD_LINE_SIZE 100
835 static void
836 monitor_load (arg)
837     char        *arg;
838 {
839   FILE *download;
840   char buf[DOWNLOAD_LINE_SIZE];
841   int i, bytes_read;
842
843   if (sr_get_debug())
844     printf ("Loading %s to monitor\n", arg);
845
846   download = fopen (arg, "r");
847   if (download == NULL)
848     {
849     error (sprintf (buf, "%s Does not exist", arg));
850     return;
851   }
852
853   printf_monitor (LOAD_CMD);
854 /*  expect ("Waiting for S-records from host... ", 1); */
855
856   while (!feof (download))
857     {
858       bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
859       if (hashmark)
860         {
861           putchar ('.');
862           fflush (stdout);
863         }
864
865       if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
866         fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
867         break;
868       }
869       i = 0;
870       while (i++ <=200000) {} ;                         /* Ugly HACK, probably needs flow control */
871       if (bytes_read < DOWNLOAD_LINE_SIZE)
872         {
873           if (!feof (download))
874             error ("Only read %d bytes\n", bytes_read);
875           break;
876         }
877     }
878
879   if (hashmark)
880     {
881       putchar ('\n');
882     }
883   if (!feof (download))
884     error ("Never got EOF while downloading");
885   fclose (download);
886 }
887
888 /* Put a command string, in args, out to MONITOR.  Output from MONITOR is placed
889    on the users terminal until the prompt is seen. */
890
891 static void
892 monitor_command (args, fromtty)
893      char       *args;
894      int        fromtty;
895 {
896 #ifdef LOG_FILE
897   fprintf (log_file, "\nIn command (args=%s)\n", args);
898 #endif
899   if (monitor_desc == NULL)
900     error("monitor target not open.");
901   
902   if (!args)
903     error("Missing command.");
904         
905   printf_monitor("%s\r", args);
906   expect_prompt(0);
907 }
908
909 #if 0
910
911 /* Connect the user directly to MONITOR.  This command acts just like the
912    'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
913
914 static struct ttystate ttystate;
915
916 static void
917 cleanup_tty()
918 {  printf("\r\n[Exiting connect mode]\r\n");
919   /*SERIAL_RESTORE(0, &ttystate);*/
920 }
921
922 static void
923 connect_command (args, fromtty)
924      char       *args;
925      int        fromtty;
926 {
927   fd_set readfds;
928   int numfds;
929   int c;
930   char cur_esc = 0;
931
932   dont_repeat();
933
934   if (monitor_desc == NULL)
935     error("monitor target not open.");
936   
937   if (args)
938     fprintf("This command takes no args.  They have been ignored.\n");
939         
940   printf("[Entering connect mode.  Use ~. or ~^D to escape]\n");
941
942   serial_raw(0, &ttystate);
943
944   make_cleanup(cleanup_tty, 0);
945
946   FD_ZERO(&readfds);
947
948   while (1)
949     {
950       do
951
952
953         {
954           FD_SET(0, &readfds);
955           FD_SET(monitor_desc, &readfds);
956           numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
957         }
958       while (numfds == 0);
959
960       if (numfds < 0)
961         perror_with_name("select");
962
963       if (FD_ISSET(0, &readfds))
964         {                       /* tty input, send to monitor */
965           c = getchar();
966           if (c < 0)
967             perror_with_name("connect");
968
969           printf_monitor("%c", c);
970           switch (cur_esc)
971             {
972             case 0:
973               if (c == '\r')
974                 cur_esc = c;
975               break;
976             case '\r':
977               if (c == '~')
978                 cur_esc = c;
979               else
980                 cur_esc = 0;
981               break;
982             case '~':
983               if (c == '.' || c == '\004')
984                 return;
985               else
986                 cur_esc = 0;
987             }
988         }
989
990       if (FD_ISSET(monitor_desc, &readfds))
991         {
992           while (1)
993             {
994               c = readchar(0);
995               if (c < 0)
996                 break;
997               putchar(c);
998             }
999           fflush(stdout);
1000         }
1001     }
1002 }
1003 #endif
1004
1005 struct target_ops rom68k_ops = {
1006   "rom68k",
1007   "Integrated System's ROM68K remote debug monitor",
1008   "Use a remote computer running the ROM68K debug monitor.\n\
1009 Specify the serial device it is connected to (e.g. /dev/ttya).",
1010   rom68k_open,
1011   monitor_close, 
1012   0,
1013   monitor_detach,
1014   monitor_resume,
1015   monitor_wait,
1016   monitor_fetch_register,
1017   monitor_store_register,
1018   monitor_prepare_to_store,
1019   monitor_xfer_inferior_memory,
1020   monitor_files_info,
1021   monitor_insert_breakpoint,
1022   monitor_remove_breakpoint,    /* Breakpoints */
1023   0,
1024   0,
1025   0,
1026   0,
1027   0,                            /* Terminal handling */
1028   monitor_kill,
1029   monitor_load,                 /* load */
1030   0,                            /* lookup_symbol */
1031   monitor_create_inferior,
1032   monitor_mourn_inferior,
1033   0,                            /* can_run */
1034   0,                            /* notice_signals */
1035   0,                            /* to_stop */
1036   process_stratum,
1037   0,                            /* next */
1038   1,
1039   1,
1040   1,
1041   1,
1042   1,                            /* all mem, mem, stack, regs, exec */
1043   0,
1044   0,                            /* Section pointers */
1045   OPS_MAGIC,                    /* Always the last thing */
1046 };
1047
1048 struct target_ops monitor_bug_ops = {
1049   "bug",
1050   "Motorola's BUG remote serial debug monitor",
1051   "Use a remote computer running Motorola's BUG debug monitor.\n\
1052 Specify the serial device it is connected to (e.g. /dev/ttya).",
1053   bug_open,
1054   monitor_close, 
1055   0,
1056   monitor_detach,
1057   monitor_resume,
1058   monitor_wait,
1059   monitor_fetch_register,
1060   monitor_store_register,
1061   monitor_prepare_to_store,
1062   monitor_xfer_inferior_memory,
1063   monitor_files_info,
1064   monitor_insert_breakpoint,
1065   monitor_remove_breakpoint,    /* Breakpoints */
1066   0,
1067   0,
1068   0,
1069   0,
1070   0,                            /* Terminal handling */
1071   monitor_kill,
1072   monitor_load,                 /* load */
1073   0,                            /* lookup_symbol */
1074   monitor_create_inferior,
1075   monitor_mourn_inferior,
1076   0,                            /* can_run */
1077   0,                            /* notice_signals */
1078   0,                            /* to_stop */
1079   process_stratum,
1080   0,                            /* next */
1081   1,
1082   1,
1083   1,
1084   1,
1085   1,                            /* all mem, mem, stack, regs, exec */
1086   0,
1087   0,                            /* Section pointers */
1088   OPS_MAGIC,                    /* Always the last thing */
1089 };
1090
1091 struct target_ops mon68_ops = {
1092   "mon68",
1093   "Intermetric's MON68 remote serial debug monitor",
1094   "Use a remote computer running the MON68 debug monitor.\n\
1095 Specify the serial device it is connected to (e.g. /dev/ttya).",
1096   mon68_open,
1097   monitor_close, 
1098   0,
1099   monitor_detach,
1100   monitor_resume,
1101   monitor_wait,
1102   monitor_fetch_register,
1103   monitor_store_register,
1104   monitor_prepare_to_store,
1105   monitor_xfer_inferior_memory,
1106   monitor_files_info,
1107   monitor_insert_breakpoint,
1108   monitor_remove_breakpoint,    /* Breakpoints */
1109   0,
1110   0,
1111   0,
1112   0,
1113   0,                            /* Terminal handling */
1114   monitor_kill,
1115   monitor_load,                 /* load */
1116   0,                            /* lookup_symbol */
1117   monitor_create_inferior,
1118   monitor_mourn_inferior,
1119   0,                            /* can_run */
1120   0,                            /* notice_signals */
1121   0,                            /* to_stop */
1122   process_stratum,
1123   0,                            /* next */
1124   1,
1125   1,
1126   1,
1127   1,
1128   1,                            /* all mem, mem, stack, regs, exec */
1129   0,
1130   0,                            /* Section pointers */
1131   OPS_MAGIC,                    /* Always the last thing */
1132 };
1133
1134
1135 /*
1136  * Define the monitor command strings. Since these are passed directly
1137  * through to a printf style function, we need can include formatting
1138  * strings. We also need a CR or LF on the end.
1139  */
1140 struct monitor_ops rom68k_cmds = {
1141   1,                                    /* 1 is ascii, 0 is binary */
1142   "\n",                                 /* monitor init string */
1143   "go \r",                              /* execute or usually GO command */
1144   "go \r",                              /* continue command */
1145   "st \r",                              /* single step */
1146   "db %x\r",                            /* set a breakpoint */
1147   "cb %x\r",                            /* clear a breakpoint */
1148   0,                                    /* 0 for number, 1 for address */
1149   {
1150   "pm %x\r",                            /* set memory to a value */
1151   "",
1152   "",
1153   },
1154   {
1155   "pm %x\r",                            /* display memory */
1156   "",
1157   "",
1158   },
1159   {
1160   "pr %s %x\r",                         /* set a register */
1161   ":  ",                                /* delimiter between registers */
1162   "",
1163   },
1164   {
1165   "pr %s\r",                            /* read a register */
1166   ":  ",                                /* delimiter between registers */
1167   "",
1168   },
1169   "dc \r",                              /* download command */
1170   "ROM68K :->",                         /* monitor command prompt */
1171   "=",                                  /* end-of-command delimitor */
1172   ".\r",                                /* optional command terminator */
1173   &rom68k_ops,                          /* target operations */
1174   "-%08X  ",                            /* prompt memory commands use */
1175 };
1176
1177 struct monitor_ops bug_cmds = {
1178   1,                                    /* 1 is ascii, 0 is binary */
1179   "\n",                                 /* monitor init string */
1180   "go \r",                              /* execute or usually GO command */
1181   "go \r",                              /* continue command */
1182   "gn \r",                              /* single step */
1183   "br %x\r",                            /* set a breakpoint */
1184   "nobr %x\r",                          /* clear a breakpoint */
1185   0,                                    /* 0 for number, 1 for address */
1186   {
1187   "mm %x\r",                            /* set memory to a value */
1188   "",
1189   "",
1190 },
1191   {
1192   "mm %x\r",                            /* display memory */
1193   "",
1194   "",
1195 },
1196   {
1197   "rs %s %x\r",                         /* set a register */
1198   "=",                                  /* delimiter between registers */
1199   "",
1200 },
1201   {
1202   "rm %s\r",                            /* read a register */
1203   "=",                                  /* delimiter between registers */
1204   "",
1205 },
1206   "lo 0\r",                             /* download command */
1207   "Bug>",                               /* monitor command prompt */
1208   "? ",                                 /* end-of-command delimitor */
1209   ".\r",                                /* optional command terminator */
1210   &monitor_bug_ops,
1211   "%08X",                               /* prompt memory commands use */
1212 };
1213
1214 #if 0
1215 /* Define the target subroutine names */
1216 struct monitor_ops mon68_cmds = {
1217   1,                                    /* 1 is ascii, 0 is binary */
1218   "",                           /* execute or usually GO command */
1219   "",                           /* continue command */
1220   "",                           /* single step */
1221   "",                           /* set a breakpoint */
1222   "",                           /* clear a breakpoint */
1223   "",                           /* set memory to a value */
1224   "",                           /* display memory */
1225   "",                           /* set a register */
1226   "",                           /* delimiter between registers */       
1227   "",                           /* read a register */
1228   "",                           /* download command */
1229   ">",                          /* monitor command prompt */
1230   "",                                   /* end-of-command delimitor */
1231   ""                                    /* optional command terminator */
1232   ""                                    /* load types */
1233 };
1234 #endif
1235
1236 void
1237 _initialize_remote_monitors ()
1238 {
1239   add_show_from_set (
1240                      add_set_cmd ("hash", no_class, var_boolean,
1241                                   (char *)&hashmark,
1242                                   "Set display of activity while downloading a file.\n\
1243 When enabled, a period \'.\' is displayed.",
1244                                   &setlist),
1245                      &showlist);
1246
1247   /* generic monitor command */
1248   add_com ("monitor <command>", class_obscure, monitor_command,
1249            "Send a command to the debug monitor."); 
1250 #if 0
1251   add_com ("connect", class_obscure, connect_command,
1252            "Connect the terminal directly up to a serial based command monitor.\n\
1253 Use <CR>~. or <CR>~^D to break out.");
1254 #endif
1255
1256   add_target (&rom68k_ops);
1257 /*  add_target (&mon68_ops); */
1258   add_target (&monitor_bug_ops);
1259 }
This page took 0.095998 seconds and 4 git commands to generate.