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