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