* som.h (som_symbol_type): Delete unwind field.
[deliverable/binutils-gdb.git] / gdb / remote-mon.c
CommitLineData
8c4731b5 1/* Remote debugging interface for boot monitors, for GDB.
c033ec17
JK
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3 Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* This file was derived from 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"
a94abe5b 52#include "remote-utils.h"
c033ec17
JK
53
54#ifdef HAVE_TERMIO
55# define TERMINAL struct termios
56#else
57# define TERMINAL struct sgttyb
58#endif
59
60struct monitor_ops *current_monitor;
61extern struct target_ops rom68k_ops; /* Forward declaration */
62extern struct target_ops mon68_ops; /* Forward declaration */
63extern struct target_ops monitor_bug_ops; /* Forward declaration */
64extern struct monitor_ops rom68k_cmds; /* Forward declaration */
65extern struct monitor_ops mon68_cmds; /* Forward declaration */
66extern struct monitor_ops bug_cmds; /* Forward declaration */
67extern struct cmd_list_element *setlist;
68extern struct cmd_list_element *unsetlist;
69struct cmd_list_element *showlist;
70
71static void monitor_close();
72static void monitor_fetch_register();
73static void monitor_store_register();
8c4731b5
RS
74#if 0
75static int sr_get_debug(); /* flag set by "set remotedebug" */
76#endif
c033ec17
JK
77static int hashmark; /* flag set by "set hash" */
78
5d76c8e6 79/* FIXME: Replace with sr_get_debug (). */
c033ec17
JK
80#define LOG_FILE "monitor.log"
81#if defined (LOG_FILE)
82FILE *log_file;
83#endif
84
85static 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 */
90static serial_t monitor_desc = NULL;
91
92/* Send data to monitor. Works just like printf. */
93
94static void
95printf_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. */
115static int
116readchar(timeout)
117 int timeout;
118{
119 int c;
120
121 c = SERIAL_READCHAR(monitor_desc, timeout);
122
8c4731b5 123 if (sr_get_debug())
c033ec17
JK
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. */
148static void
149expect(string, discard)
150 char *string;
151 int discard;
152{
153 char *p = string;
154 int c;
155
8c4731b5 156 if (sr_get_debug())
c033ec17
JK
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;
8c4731b5 170 if (sr_get_debug())
c033ec17
JK
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. */
202static void
203expect_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). */
216static int
217get_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. */
242static void
243get_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. */
255static void
256get_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. */
276static void
277monitor_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
c033ec17
JK
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? */
45dc9be3
JK
312
313 /* Let 'er rip... */
314 proceed ((CORE_ADDR)entry_pt, TARGET_SIGNAL_DEFAULT, 0);
c033ec17
JK
315}
316
317/* Open a connection to a remote debugger.
318 NAME is the filename used for communication. */
319
320static int baudrate = 9600;
321static char dev_name[100];
322
323static void
324general_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
8c4731b5
RS
335/* if (is_open) */
336 monitor_close(0);
c033ec17 337
8c4731b5 338 strcpy(dev_name, args);
c033ec17
JK
339 monitor_desc = SERIAL_OPEN(dev_name);
340
341 if (monitor_desc == NULL)
342 perror_with_name(dev_name);
343
c20c1bdf 344 if (baud_rate != -1)
c033ec17 345 {
c20c1bdf
JK
346 if (SERIAL_SETBAUDRATE (monitor_desc, baud_rate))
347 {
348 SERIAL_CLOSE (monitor_desc);
349 perror_with_name (name);
350 }
c033ec17
JK
351 }
352
353 SERIAL_RAW(monitor_desc);
354
355#if defined (LOG_FILE)
356 log_file = fopen (LOG_FILE, "w");
357 if (log_file == NULL)
358 perror_with_name (LOG_FILE);
359#endif
360
361 /* Hello? Are you there? */
362 printf_monitor("\r"); /* CR wakes up monitor */
363
364 expect_prompt(1);
365
366 if (from_tty)
367 printf("Remote %s connected to %s\n", target_shortname,
368 dev_name);
369}
370
371static void
372rom68k_open(args, from_tty)
373 char *args;
374 int from_tty;
375{
376 push_target(&rom68k_ops);
377 push_monitor (&rom68k_cmds);
378
379 general_open (args, "rom68k", from_tty);
380}
381
382static void
383mon68_open(args, from_tty)
384 char *args;
385 int from_tty;
386{
387 push_target(&mon68_ops);
388 push_monitor (&mon68_cmds);
389
390 general_open (args, "mon68", from_tty);
391}
392
393static void
394bug_open(args, from_tty)
395 char *args;
396 int from_tty;
397{
398 push_target(&monitor_bug_ops);
399 push_monitor (&bug_cmds);
400
401 general_open (args, "bug", from_tty);
402}
403
404/*
405 * _close -- Close out all files and local state before this target loses control.
406 */
407
408static void
409monitor_close (quitting)
410 int quitting;
411{
412 SERIAL_CLOSE(monitor_desc);
413 monitor_desc = NULL;
414
415#if defined (LOG_FILE)
416 if (log_file) {
417 if (ferror(log_file))
418 fprintf(stderr, "Error writing log file.\n");
419 if (fclose(log_file) != 0)
420 fprintf(stderr, "Error closing log file.\n");
421 }
422#endif
423}
424
425/* Terminate the open connection to the remote debugger.
426 Use this when you want to detach and do something else
427 with your gdb. */
428static void
429monitor_detach (from_tty)
430 int from_tty;
431{
432 pop_target(); /* calls monitor_close to do the real work */
433 if (from_tty)
434 printf ("Ending remote %s debugging\n", target_shortname);
435}
436
437/*
438 * _resume -- Tell the remote machine to resume.
439 */
440static void
441monitor_resume (pid, step, sig)
67ac9759
JK
442 int pid, step;
443 enum target_signal sig;
c033ec17
JK
444{
445#ifdef LOG_FILE
446 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
447#endif
448
449 if (step)
450 {
451 printf_monitor (STEP_CMD);
452 /* wait for the echo. */
453 expect (STEP_CMD, 1);
454 }
455 else
456 {
457 printf_monitor (GO_CMD);
458 /* swallow the echo. */
459 expect (GO_CMD, 1);
460 }
461}
462
463/*
464 * _wait -- Wait until the remote machine stops, then return,
465 * storing status in status just as `wait' would.
466 */
467
468static int
de43d7d0
SG
469monitor_wait (pid, status)
470 int pid;
67ac9759 471 struct target_waitstatus *status;
c033ec17
JK
472{
473 int old_timeout = timeout;
474#ifdef LOG_FILE
475 fputs ("\nIn wait ()", log_file);
476#endif
477
67ac9759
JK
478 status->kind = TARGET_WAITKIND_EXITED;
479 status->value.integer = 0;
c033ec17
JK
480
481 timeout = 0; /* Don't time out -- user program is running. */
482
483 expect_prompt(0); /* Wait for prompt, outputting extraneous text */
484
67ac9759
JK
485 status->kind = TARGET_WAITKIND_STOPPED;
486 status->value.sig = TARGET_SIGNAL_TRAP;
c033ec17
JK
487
488 timeout = old_timeout;
489
490 return 0;
491}
492
493/* Return the name of register number regno in the form input and output by
494 monitor. Currently, register_names just happens to contain exactly what
495 monitor wants. Lets take advantage of that just as long as possible! */
496
497static char *
498get_reg_name (regno)
499 int regno;
500{
501 static char buf[50];
502 const char *p;
503 char *b;
504
505 b = buf;
506
507 if (regno < 0)
508 return ("");
509 for (p = reg_names[regno]; *p; p++)
510 *b++ = toupper(*p);
511 *b = '\000';
512
513 return buf;
514}
515
516/* read the remote registers into the block regs. */
517
518static void
519monitor_fetch_registers ()
520{
521 int regno;
522
523 /* yeah yeah, i know this is horribly inefficient. but it isn't done
524 very often... i'll clean it up later. */
525
526 for (regno = 0; regno <= PC_REGNUM; regno++)
527 monitor_fetch_register(regno);
528}
529
530/* Fetch register REGNO, or all registers if REGNO is -1.
531 Returns errno value. */
532static void
533monitor_fetch_register (regno)
534 int regno;
535{
536 int val, j;
537
538#ifdef LOG_FILE
539 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
540 fflush (log_file);
541#endif
542
543 if (regno < 0)
544 {
545 monitor_fetch_registers ();
546 }
547 else
548 {
549 char *name = get_reg_name (regno);
550 printf_monitor (GET_REG, name);
551 expect (name, 1);
552 expect (REG_DELIM, 1);
553 if (strcasecmp (name, "SR") == 0)
554 {
555 val = 0;
556 for (j = 0; j < 4; j++)
557 val = (val << 4) + get_hex_digit (j == 0);
558 supply_register (regno, (char *) &val);
559 }
560 else
561 {
562 get_hex_regs (1, regno);
563 }
564 if (CMD_END)
565 {
566 expect (CMD_DELIM);
567 printf_monitor (CMD_END);
568 }
569 expect_prompt (1);
570 }
571 return;
572}
573
574/* Store the remote registers from the contents of the block REGS. */
575
576static void
577monitor_store_registers ()
578{
579 int regno;
580
581 for (regno = 0; regno <= PC_REGNUM; regno++)
582 monitor_store_register(regno);
583
584 registers_changed ();
585}
586
587/* Store register REGNO, or all if REGNO == 0.
588 return errno value. */
589static void
590monitor_store_register (regno)
591 int regno;
592{
593#ifdef LOG_FILE
594 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
595#endif
596 if (regno == -1)
597 monitor_store_registers ();
598 else
599 {
8c4731b5 600 if (sr_get_debug())
c033ec17
JK
601 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
602
603 printf_monitor (SET_REG, get_reg_name (regno),
604 read_register (regno));
605
606 expect_prompt (1);
607 }
608}
609
610/* Get ready to modify the registers array. On machines which store
611 individual registers, this doesn't need to do anything. On machines
612 which store all the registers in one fell swoop, this makes sure
613 that registers contains all the registers from the program being
614 debugged. */
615
616static void
617monitor_prepare_to_store ()
618{
619 /* Do nothing, since we can store individual regs */
620}
621
622static void
623monitor_files_info ()
624{
625 printf ("\tAttached to %s at %d baud.\n",
626 dev_name, baudrate);
627}
628
629/* Copy LEN bytes of data from debugger memory at MYADDR
630 to inferior's memory at MEMADDR. Returns length moved. */
631static int
632monitor_write_inferior_memory (memaddr, myaddr, len)
633 CORE_ADDR memaddr;
634 unsigned char *myaddr;
635 int len;
636{
637 int i;
638 char buf[10];
639
640#ifdef LOG_FILE
641 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
642#endif
643 for (i = 0; i < len; i++)
644 {
645 printf_monitor (MEM_SET_CMD, memaddr + i);
646 expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1);
647 expect (CMD_DELIM);
648 printf_monitor ("%x", myaddr[i]);
8c4731b5 649 if (sr_get_debug())
c033ec17
JK
650 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
651 if (CMD_END)
652 {
653/*** expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);
654 expect (CMD_DELIM); ***/
655 printf_monitor (CMD_END);
656 }
657 expect_prompt (1);
658 }
659 return len;
660}
661
662/* Read LEN bytes from inferior memory at MEMADDR. Put the result
663 at debugger address MYADDR. Returns length moved. */
664static int
665monitor_read_inferior_memory(memaddr, myaddr, len)
666 CORE_ADDR memaddr;
667 char *myaddr;
668 int len;
669{
670 int i, j;
671 char buf[20];
672
673 /* Number of bytes read so far. */
674 int count;
675
676 /* Starting address of this pass. */
677 unsigned long startaddr;
678
679 /* Number of bytes to read in this pass. */
680 int len_this_pass;
681
682#ifdef LOG_FILE
683 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
684#endif
685
686 /* Note that this code works correctly if startaddr is just less
687 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
688 thing). That is, something like
689 monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
690 works--it never adds len To memaddr and gets 0. */
691 /* However, something like
692 monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
693 doesn't need to work. Detect it and give up if there's an attempt
694 to do that. */
695 if (((memaddr - 1) + len) < memaddr) {
696 errno = EIO;
697 return 0;
698 }
699
700 startaddr = memaddr;
701 count = 0;
702 while (count < len)
703 {
704 len_this_pass = 16;
705 if ((startaddr % 16) != 0)
706 len_this_pass -= startaddr % 16;
707 if (len_this_pass > (len - count))
708 len_this_pass = (len - count);
8c4731b5 709 if (sr_get_debug())
c033ec17
JK
710 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
711
712 for (i = 0; i < len_this_pass; i++)
713 {
714 printf_monitor (MEM_DIS_CMD, startaddr);
715 expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
716 get_hex_byte (&myaddr[count++]);
8c4731b5 717 if (sr_get_debug())
c033ec17
JK
718 printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
719 if (CMD_END)
720 {
721 expect (CMD_DELIM);
722 printf_monitor (CMD_END);
723 }
724 expect_prompt (1);
725 startaddr += 1;
726 }
727 }
728 return len;
729}
730
731/* FIXME-someday! merge these two. */
732static int
733monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
734 CORE_ADDR memaddr;
735 char *myaddr;
736 int len;
737 int write;
738 struct target_ops *target; /* ignored */
739{
740 if (write)
741 return monitor_write_inferior_memory (memaddr, myaddr, len);
742 else
743 return monitor_read_inferior_memory (memaddr, myaddr, len);
744}
745
746static void
747monitor_kill (args, from_tty)
748 char *args;
749 int from_tty;
750{
751 return; /* ignore attempts to kill target system */
752}
753
754/* Clean up when a program exits.
755 The program actually lives on in the remote processor's RAM, and may be
756 run again without a download. Don't leave it full of breakpoint
757 instructions. */
758
759static void
760monitor_mourn_inferior ()
761{
762 remove_breakpoints ();
763 generic_mourn_inferior (); /* Do all the proper things now */
764}
765
766#define MAX_MONITOR_BREAKPOINTS 16
767
768extern int memory_breakpoint_size;
769static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
770
771static int
772monitor_insert_breakpoint (addr, shadow)
773 CORE_ADDR addr;
774 char *shadow;
775{
776 int i;
777
778#ifdef LOG_FILE
779 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
780#endif
781 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
782 if (breakaddr[i] == 0)
783 {
784 breakaddr[i] = addr;
8c4731b5 785 if (sr_get_debug())
c033ec17
JK
786 printf ("Breakpoint at %x\n", addr);
787 monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
788 printf_monitor(SET_BREAK_CMD, addr);
789 expect_prompt(1);
790 return 0;
791 }
792
793 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
794 return 1;
795}
796
797/*
798 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
799 */
800static int
801monitor_remove_breakpoint (addr, shadow)
802 CORE_ADDR addr;
803 char *shadow;
804{
805 int i;
806
807#ifdef LOG_FILE
808 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
809#endif
810 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
811 if (breakaddr[i] == addr)
812 {
813 breakaddr[i] = 0;
814 /* some monitors remove breakpoints based on the address */
815 if (strcasecmp (target_shortname, "bug") == 0)
816 printf_monitor(CLR_BREAK_CMD, addr);
817 else
818 printf_monitor(CLR_BREAK_CMD, i);
819 expect_prompt(1);
820 return 0;
821 }
822
823 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
824 return 1;
825}
826
827/* Load a file. This is usually an srecord, which is ascii. No
828 protocol, just sent line by line. */
829
830#define DOWNLOAD_LINE_SIZE 100
831static void
832monitor_load (arg)
833 char *arg;
834{
835 FILE *download;
836 char buf[DOWNLOAD_LINE_SIZE];
837 int i, bytes_read;
838
8c4731b5 839 if (sr_get_debug())
c033ec17
JK
840 printf ("Loading %s to monitor\n", arg);
841
842 download = fopen (arg, "r");
843 if (download == NULL)
844 {
845 error (sprintf (buf, "%s Does not exist", arg));
846 return;
847 }
848
849 printf_monitor (LOAD_CMD);
850/* expect ("Waiting for S-records from host... ", 1); */
851
852 while (!feof (download))
853 {
854 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
855 if (hashmark)
856 {
857 putchar ('.');
858 fflush (stdout);
859 }
860
861 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
862 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
863 break;
864 }
865 i = 0;
866 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
867 if (bytes_read < DOWNLOAD_LINE_SIZE)
868 {
869 if (!feof (download))
870 error ("Only read %d bytes\n", bytes_read);
871 break;
872 }
873 }
874
875 if (hashmark)
876 {
877 putchar ('\n');
878 }
879 if (!feof (download))
880 error ("Never got EOF while downloading");
881 fclose (download);
882}
883
884/* Put a command string, in args, out to MONITOR. Output from MONITOR is placed
885 on the users terminal until the prompt is seen. */
886
887static void
888monitor_command (args, fromtty)
889 char *args;
890 int fromtty;
891{
892#ifdef LOG_FILE
893 fprintf (log_file, "\nIn command (args=%s)\n", args);
894#endif
895 if (monitor_desc == NULL)
896 error("monitor target not open.");
897
898 if (!args)
899 error("Missing command.");
900
901 printf_monitor("%s\r", args);
902 expect_prompt(0);
903}
904
905#if 0
906
907/* Connect the user directly to MONITOR. This command acts just like the
908 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
909
910static struct ttystate ttystate;
911
912static void
913cleanup_tty()
914{ printf("\r\n[Exiting connect mode]\r\n");
915 /*SERIAL_RESTORE(0, &ttystate);*/
916}
917
918static void
919connect_command (args, fromtty)
920 char *args;
921 int fromtty;
922{
923 fd_set readfds;
924 int numfds;
925 int c;
926 char cur_esc = 0;
927
928 dont_repeat();
929
930 if (monitor_desc == NULL)
931 error("monitor target not open.");
932
933 if (args)
934 fprintf("This command takes no args. They have been ignored.\n");
935
936 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
937
938 serial_raw(0, &ttystate);
939
940 make_cleanup(cleanup_tty, 0);
941
942 FD_ZERO(&readfds);
943
944 while (1)
945 {
946 do
947 {
948 FD_SET(0, &readfds);
949 FD_SET(monitor_desc, &readfds);
950 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
951 }
952 while (numfds == 0);
953
954 if (numfds < 0)
955 perror_with_name("select");
956
957 if (FD_ISSET(0, &readfds))
958 { /* tty input, send to monitor */
959 c = getchar();
960 if (c < 0)
961 perror_with_name("connect");
962
963 printf_monitor("%c", c);
964 switch (cur_esc)
965 {
966 case 0:
967 if (c == '\r')
968 cur_esc = c;
969 break;
970 case '\r':
971 if (c == '~')
972 cur_esc = c;
973 else
974 cur_esc = 0;
975 break;
976 case '~':
977 if (c == '.' || c == '\004')
978 return;
979 else
980 cur_esc = 0;
981 }
982 }
983
984 if (FD_ISSET(monitor_desc, &readfds))
985 {
986 while (1)
987 {
988 c = readchar(0);
989 if (c < 0)
990 break;
991 putchar(c);
992 }
993 fflush(stdout);
994 }
995 }
996}
997#endif
998
999/*
1000 * Define the monitor command strings. Since these are passed directly
1001 * through to a printf style function, we need can include formatting
1002 * strings. We also need a CR or LF on the end.
1003 */
1004struct monitor_ops rom68k_cmds = {
1005 "go \r", /* execute or usually GO command */
1006 "go \r", /* continue command */
1007 "st \r", /* single step */
1008 "db %x\r", /* set a breakpoint */
1009 "cb %x\r", /* clear a breakpoint */
1010 "pm %x\r", /* set memory to a value */
1011 "pm %x\r", /* display memory */
1012 "-%08X ", /* prompt memory commands use */
1013 "pr %s %x\r", /* set a register */
1014 ": ", /* delimiter between registers */
1015 "pr %s\r", /* read a register */
1016 "dc \r", /* download command */
1017 "ROM68K :->", /* monitor command prompt */
1018 "=", /* end-of-command delimitor */
1019 ".\r" /* optional command terminator */
1020};
1021
1022struct monitor_ops bug_cmds = {
1023 "go \r", /* execute or usually GO command */
1024 "go \r", /* continue command */
1025 "gn \r", /* single step */
1026 "br %x\r", /* set a breakpoint */
1027 "nobr %x\r", /* clear a breakpoint */
1028 "mm %x\r", /* set memory to a value */
1029 "mm %x\r", /* display memory */
1030 "%08X", /* prompt memory commands use */
1031 "rs %s %x\r", /* set a register */
1032 "=", /* delimiter between registers */
1033 "rm %s\r", /* read a register */
1034 "lo 0\r", /* download command */
1035 "Bug>", /* monitor command prompt */
1036 "? ", /* end-of-command delimitor */
1037 ".\r" /* optional command terminator */
1038};
1039
1040/* Define the target subroutine names */
1041struct monitor_ops mon68_cmds = {
1042 "", /* execute or usually GO command */
1043 "", /* continue command */
1044 "", /* single step */
1045 "", /* set a breakpoint */
1046 "", /* clear a breakpoint */
1047 "", /* set memory to a value */
1048 "", /* display memory */
1049 "", /* set a register */
1050 "", /* delimiter between registers */
1051 "", /* read a register */
1052 "", /* download command */
1053 ">", /* monitor command prompt */
1054 "", /* end-of-command delimitor */
1055 "" /* optional command terminator */
1056};
1057
1058struct target_ops rom68k_ops = {
1059 "rom68k",
1060 "Integrated System's ROM68K remote debug monitor",
1061 "Use a remote computer running the ROM68K debug monitor.\n\
1062Specify the serial device it is connected to (e.g. /dev/ttya).",
1063 rom68k_open,
1064 monitor_close,
1065 0,
1066 monitor_detach,
1067 monitor_resume,
1068 monitor_wait,
1069 monitor_fetch_register,
1070 monitor_store_register,
1071 monitor_prepare_to_store,
1072 monitor_xfer_inferior_memory,
1073 monitor_files_info,
1074 monitor_insert_breakpoint,
1075 monitor_remove_breakpoint, /* Breakpoints */
1076 0,
1077 0,
1078 0,
1079 0,
1080 0, /* Terminal handling */
1081 monitor_kill,
1082 monitor_load, /* load */
1083 0, /* lookup_symbol */
1084 monitor_create_inferior,
1085 monitor_mourn_inferior,
1086 0, /* can_run */
1087 0, /* notice_signals */
1088 process_stratum,
1089 0, /* next */
1090 1,
1091 1,
1092 1,
1093 1,
1094 1, /* all mem, mem, stack, regs, exec */
1095 0,
1096 0, /* Section pointers */
1097 OPS_MAGIC, /* Always the last thing */
1098};
1099
1100struct target_ops monitor_bug_ops = {
1101 "bug",
1102 "Motorola's BUG remote serial debug monitor",
1103 "Use a remote computer running Motorola's BUG debug monitor.\n\
1104Specify the serial device it is connected to (e.g. /dev/ttya).",
1105 bug_open,
1106 monitor_close,
1107 0,
1108 monitor_detach,
1109 monitor_resume,
1110 monitor_wait,
1111 monitor_fetch_register,
1112 monitor_store_register,
1113 monitor_prepare_to_store,
1114 monitor_xfer_inferior_memory,
1115 monitor_files_info,
1116 monitor_insert_breakpoint,
1117 monitor_remove_breakpoint, /* Breakpoints */
1118 0,
1119 0,
1120 0,
1121 0,
1122 0, /* Terminal handling */
1123 monitor_kill,
1124 monitor_load, /* load */
1125 0, /* lookup_symbol */
1126 monitor_create_inferior,
1127 monitor_mourn_inferior,
1128 0, /* can_run */
1129 0, /* notice_signals */
1130 process_stratum,
1131 0, /* next */
1132 1,
1133 1,
1134 1,
1135 1,
1136 1, /* all mem, mem, stack, regs, exec */
1137 0,
1138 0, /* Section pointers */
1139 OPS_MAGIC, /* Always the last thing */
1140};
1141
1142struct target_ops mon68_ops = {
1143 "mon68",
1144 "Intermetric's MON68 remote serial debug monitor",
1145 "Use a remote computer running the MON68 debug monitor.\n\
1146Specify the serial device it is connected to (e.g. /dev/ttya).",
1147 mon68_open,
1148 monitor_close,
1149 0,
1150 monitor_detach,
1151 monitor_resume,
1152 monitor_wait,
1153 monitor_fetch_register,
1154 monitor_store_register,
1155 monitor_prepare_to_store,
1156 monitor_xfer_inferior_memory,
1157 monitor_files_info,
1158 monitor_insert_breakpoint,
1159 monitor_remove_breakpoint, /* Breakpoints */
1160 0,
1161 0,
1162 0,
1163 0,
1164 0, /* Terminal handling */
1165 monitor_kill,
1166 monitor_load, /* load */
1167 0, /* lookup_symbol */
1168 monitor_create_inferior,
1169 monitor_mourn_inferior,
1170 0, /* can_run */
1171 0, /* notice_signals */
1172 process_stratum,
1173 0, /* next */
1174 1,
1175 1,
1176 1,
1177 1,
1178 1, /* all mem, mem, stack, regs, exec */
1179 0,
1180 0, /* Section pointers */
1181 OPS_MAGIC, /* Always the last thing */
1182};
1183
1184void
1185_initialize_remote_monitors ()
1186{
c033ec17
JK
1187 add_show_from_set (
1188 add_set_cmd ("hash", no_class, var_boolean,
1189 (char *)&hashmark,
1190 "Set display of activity while downloading a file.\n\
1191When enabled, a period \'.\' is displayed.",
1192 &setlist),
1193 &showlist);
1194
1195 /* generic monitor command */
1196 add_com ("monitor <command>", class_obscure, monitor_command,
1197 "Send a command to the debug monitor.");
1198#if 0
1199 add_com ("connect", class_obscure, connect_command,
1200 "Connect the terminal directly up to a serial based command monitor.\n\
1201Use <CR>~. or <CR>~^D to break out.");
1202#endif
1203
1204 add_target (&rom68k_ops);
1205/* add_target (&mon68_ops); */
1206 add_target (&monitor_bug_ops);
1207}
This page took 0.368155 seconds and 4 git commands to generate.