1 /* Remote debugging interface for boot monitors, for GDB.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* This file was derived from remote-eb.c, which did a similar job, but for
21 an AMD-29K running EBMON. That file was in turn derived from remote.c
22 as mentioned in the following comment (left in for comic relief):
24 "This is like remote.c but is for a different situation--
25 having a PC running os9000 hook up with a unix machine with
26 a serial line, and running ctty com2 on the PC. os9000 has a debug
27 monitor called ROMBUG running. Not to mention that the PC
28 has PC/NFS, so it can access the same executables that gdb can,
29 over the net in real time."
31 In reality, this module talks to a debug monitor called 'ROMBUG', which
32 We communicate with ROMBUG via a direct serial line, the network version
33 of ROMBUG is not available yet.
43 #include <sys/types.h>
47 #include "remote-utils.h"
51 #include "gdb-stabs.h"
55 # define TERMINAL struct termios
57 # define TERMINAL struct sgttyb
60 struct monitor_ops *current_monitor;
61 struct cmd_list_element *showlist;
62 extern struct target_ops rombug_ops; /* Forward declaration */
63 extern struct monitor_ops rombug_cmds; /* Forward declaration */
64 extern struct cmd_list_element *setlist;
65 extern struct cmd_list_element *unsetlist;
66 extern int attach_flag;
68 static void rombug_close();
69 static void rombug_fetch_register();
70 static void rombug_fetch_registers();
71 static void rombug_store_register();
73 static int sr_get_debug(); /* flag set by "set remotedebug" */
75 static int hashmark; /* flag set by "set hash" */
76 static int rombug_is_open = 0;
78 /* FIXME: Replace with sr_get_debug (). */
79 #define LOG_FILE "monitor.log"
81 static int monitor_log = 0;
82 static int tty_xon = 0;
83 static int tty_xoff = 0;
85 static int timeout = 10;
86 static int is_trace_mode = 0;
87 /* Descriptor for I/O to remote machine. Initialize it to NULL*/
88 static serial_t monitor_desc = NULL;
90 static CORE_ADDR bufaddr = 0;
91 static int buflen = 0;
92 static char readbuf[16];
94 /* Send data to monitor. Works just like printf. */
96 printf_monitor(va_alist)
106 pattern = va_arg(args, char *);
108 vsprintf(buf, pattern, args);
110 if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
111 fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
114 /* Read a character from the remote system, doing all the fancy timeout stuff*/
121 c = SERIAL_READCHAR(monitor_desc, timeout);
126 if (monitor_log && isascii(c))
127 putc(c & 0x7f, log_file);
132 if (c == SERIAL_TIMEOUT)
135 return c; /* Polls shouldn't generate timeout errors */
137 error("Timeout reading from remote system.");
140 perror_with_name("remote-monitor");
143 /* Scan input from the remote system, until STRING is found. If DISCARD is
144 non-zero, then discard non-matching input, else print it out.
145 Let the user break out immediately. */
147 expect(string, discard)
155 printf ("Expecting \"%s\"\n", string);
160 c = readchar(timeout);
169 printf ("\nMatched\n");
177 fwrite(string, 1, (p - 1) - string, stdout);
186 /* Keep discarding input until we see the ROMBUG prompt.
188 The convention for dealing with the prompt is that you
190 o *then* wait for the prompt.
192 Thus the last thing that a procedure does with the serial line
193 will be an expect_prompt(). Exception: rombug_resume does not
194 wait for the prompt, because the terminal is being handed over
195 to the inferior. However, the next thing which happens after that
196 is a rombug_wait which does wait for the prompt.
197 Note that this includes abnormal exit, e.g. error(). This is
198 necessary to prevent getting into states from which we can't
201 expect_prompt(discard)
205 /* This is a convenient place to do this. The idea is to do it often
206 enough that we never lose much data if we terminate abnormally. */
210 expect("trace", discard);
212 expect (PROMPT, discard);
216 /* Get a hex digit from the remote system & return its value.
217 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
219 get_hex_digit(ignore_space)
225 ch = readchar(timeout);
226 if (ch >= '0' && ch <= '9')
228 else if (ch >= 'A' && ch <= 'F')
229 return ch - 'A' + 10;
230 else if (ch >= 'a' && ch <= 'f')
231 return ch - 'a' + 10;
232 else if (ch == ' ' && ignore_space)
237 error("Invalid hex digit from remote system.");
242 /* Get a byte from monitor and put it in *BYT. Accept any number
250 val = get_hex_digit (1) << 4;
251 val |= get_hex_digit (0);
255 /* Get N 32-bit words from remote, each preceded by a space,
256 and put them in registers starting at REGNO. */
258 get_hex_regs (n, regno)
266 for (i = 0; i < n; i++)
271 for (j = 0; j < 4; j++)
273 #if TARGET_BYTE_ORDER == BIG_ENDIAN
275 val = (val << 8) + b;
278 val = val + (b << (j*8));
281 supply_register (regno++, (char *) &val);
285 /* This is called not only when we first attach, but also when the
286 user types "run" after having attached. */
288 rombug_create_inferior (execfile, args, env)
296 error("Can't pass arguments to remote ROMBUG process");
298 if (execfile == 0 || exec_bfd == 0)
299 error("No exec file specified");
301 entry_pt = (int) bfd_get_start_address (exec_bfd);
304 fputs ("\nIn Create_inferior()", log_file);
307 /* The "process" (board) is already stopped awaiting our commands, and
308 the program is already downloaded. We just set its PC and go. */
310 init_wait_for_inferior ();
311 proceed ((CORE_ADDR)entry_pt, TARGET_SIGNAL_DEFAULT, 0);
314 /* Open a connection to a remote debugger.
315 NAME is the filename used for communication. */
317 static char dev_name[100];
320 rombug_open(args, from_tty)
325 error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
326 `target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
328 target_preopen(from_tty);
331 unpush_target(&rombug_ops);
333 strcpy(dev_name, args);
334 monitor_desc = SERIAL_OPEN(dev_name);
335 if (monitor_desc == NULL)
336 perror_with_name(dev_name);
338 /* if baud rate is set by 'set remotebaud' */
339 if (SERIAL_SETBAUDRATE (monitor_desc, sr_get_baud_rate()))
341 SERIAL_CLOSE (monitor_desc);
342 perror_with_name ("RomBug");
344 SERIAL_RAW(monitor_desc);
345 if (tty_xon || tty_xoff)
347 struct hardware_ttystate { struct termios t;} *tty_s;
349 tty_s =(struct hardware_ttystate *)SERIAL_GET_TTY_STATE(monitor_desc);
350 if (tty_xon) tty_s->t.c_iflag |= IXON;
351 if (tty_xoff) tty_s->t.c_iflag |= IXOFF;
352 SERIAL_SET_TTY_STATE(monitor_desc, (serial_ttystate) tty_s);
357 log_file = fopen (LOG_FILE, "w");
358 if (log_file == NULL)
359 perror_with_name (LOG_FILE);
361 push_monitor (&rombug_cmds);
362 printf_monitor("\r"); /* CR wakes up monitor */
365 push_target (&rombug_ops);
367 printf("Remote %s connected to %s\n", target_shortname,
371 rombug_fetch_registers();
377 * Close out all files and local state before this target loses control.
381 rombug_close (quitting)
384 if (rombug_is_open) {
385 SERIAL_CLOSE(monitor_desc);
391 if (ferror(log_file))
392 fprintf(stderr, "Error writing log file.\n");
393 if (fclose(log_file) != 0)
394 fprintf(stderr, "Error closing log file.\n");
400 rombug_link(mod_name, text_reloc)
402 CORE_ADDR *text_reloc;
408 printf_monitor("l %s \r", mod_name);
410 printf_monitor(".r \r");
411 expect(REG_DELIM, 1);
412 for (i=0; i <= 7; i++)
415 for (j = 0; j < 4; j++)
418 val = (val << 8) + b;
426 /* Terminate the open connection to the remote debugger.
427 Use this when you want to detach and do something else
430 rombug_detach (from_tty)
434 printf_monitor (GO_CMD);
437 pop_target(); /* calls rombug_close to do the real work */
439 printf ("Ending remote %s debugging\n", target_shortname);
443 * Tell the remote machine to resume.
446 rombug_resume (pid, step, sig)
448 enum target_signal sig;
451 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
456 printf_monitor (STEP_CMD);
457 /* wait for the echo. **
458 expect (STEP_CMD, 1);
463 printf_monitor (GO_CMD);
464 /* swallow the echo. **
473 * Wait until the remote machine stops, then return,
474 * storing status in status just as `wait' would.
478 rombug_wait (pid, status)
480 struct target_waitstatus *status;
482 int old_timeout = timeout;
483 struct section_offsets *offs;
485 struct obj_section *obj_sec;
488 fputs ("\nIn wait ()", log_file);
490 status->kind = TARGET_WAITKIND_EXITED;
491 status->value.integer = 0;
493 timeout = 0; /* Don't time out -- user program is running. */
494 expect_prompt(1); /* Wait for prompt, outputting extraneous text */
496 status->kind = TARGET_WAITKIND_STOPPED;
497 status->value.sig = TARGET_SIGNAL_TRAP;
498 timeout = old_timeout;
499 rombug_fetch_registers();
502 pc = read_register(PC_REGNUM);
503 addr = read_register(DATABASE_REG);
504 obj_sec = find_pc_section (pc);
507 if (obj_sec->objfile != symfile_objfile)
508 new_symfile_objfile(obj_sec->objfile, 1, 0);
509 offs = ((struct section_offsets *)
510 alloca (sizeof (struct section_offsets)
511 + (symfile_objfile->num_sections * sizeof (offs->offsets))));
512 memcpy (offs, symfile_objfile->section_offsets,
513 (sizeof (struct section_offsets) +
514 (symfile_objfile->num_sections * sizeof (offs->offsets))));
515 ANOFFSET (offs, SECT_OFF_DATA) = addr;
516 ANOFFSET (offs, SECT_OFF_BSS) = addr;
518 objfile_relocate(symfile_objfile, offs);
524 /* Return the name of register number regno in the form input and output by
525 monitor. Currently, register_names just happens to contain exactly what
526 monitor wants. Lets take advantage of that just as long as possible! */
541 for (p = reg_names[regno]; *p; p++)
545 p = (char *)reg_names[regno];
552 /* read the remote registers into the block regs. */
555 rombug_fetch_registers ()
561 printf_monitor (GET_REG);
572 for (regno = 8; regno <= 15; regno++)
574 expect(REG_DELIM, 1);
575 if (regno >= 8 && regno <= 13)
578 for (j = 0; j < 2; j++)
580 #if TARGET_BYTE_ORDER == BIG_ENDIAN
582 val = (val << 8) + b;
585 val = val + (b << (j*8));
589 if (regno == 8) i = 10;
590 if (regno >= 9 && regno <= 12) i = regno + 3;
591 if (regno == 13) i = 11;
592 supply_register (i, (char *) &val);
594 else if (regno == 14)
596 get_hex_regs(1, PC_REGNUM);
598 else if (regno == 15)
605 supply_register(regno, (char *) &val);
612 /* Fetch register REGNO, or all registers if REGNO is -1.
613 Returns errno value. */
615 rombug_fetch_register (regno)
622 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
628 rombug_fetch_registers ();
632 char *name = get_reg_name (regno);
633 printf_monitor (GET_REG);
634 if (regno >= 10 && regno <= 15)
639 expect (REG_DELIM, 1);
641 for (j = 0; j < 2; j++)
643 #if TARGET_BYTE_ORDER == BIG_ENDIAN
645 val = (val << 8) + b;
648 val = val + (b << (j*8));
651 supply_register (regno, (char *) &val);
653 else if (regno == 8 || regno == 9)
659 expect (REG_DELIM, 1);
660 get_hex_regs (1, regno);
665 expect (REG_DELIM, 1);
681 /* Store the remote registers from the contents of the block REGS. */
684 rombug_store_registers ()
688 for (regno = 0; regno <= PC_REGNUM; regno++)
689 rombug_store_register(regno);
691 registers_changed ();
694 /* Store register REGNO, or all if REGNO == 0.
695 return errno value. */
697 rombug_store_register (regno)
703 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
706 rombug_store_registers ();
710 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
712 name = get_reg_name(regno);
713 if (name == 0) return;
714 printf_monitor (SET_REG, name, read_register (regno));
721 /* Get ready to modify the registers array. On machines which store
722 individual registers, this doesn't need to do anything. On machines
723 which store all the registers in one fell swoop, this makes sure
724 that registers contains all the registers from the program being
728 rombug_prepare_to_store ()
730 /* Do nothing, since we can store individual regs */
736 printf ("\tAttached to %s at %d baud.\n",
737 dev_name, sr_get_baud_rate());
740 /* Copy LEN bytes of data from debugger memory at MYADDR
741 to inferior's memory at MEMADDR. Returns length moved. */
743 rombug_write_inferior_memory (memaddr, myaddr, len)
745 unsigned char *myaddr;
752 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
754 printf_monitor (MEM_SET_CMD, memaddr);
755 for (i = 0; i < len; i++)
757 expect (CMD_DELIM, 1);
758 printf_monitor ("%x \r", myaddr[i]);
760 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
762 expect (CMD_DELIM, 1);
764 printf_monitor (CMD_END);
771 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
772 at debugger address MYADDR. Returns length moved. */
774 rombug_read_inferior_memory(memaddr, myaddr, len)
781 /* Number of bytes read so far. */
784 /* Starting address of this pass. */
785 unsigned long startaddr;
787 /* Number of bytes to read in this pass. */
791 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
793 /* Note that this code works correctly if startaddr is just less
794 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
795 thing). That is, something like
796 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
797 works--it never adds len To memaddr and gets 0. */
798 /* However, something like
799 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
800 doesn't need to work. Detect it and give up if there's an attempt
802 if (((memaddr - 1) + len) < memaddr) {
806 if (bufaddr <= memaddr && (memaddr+len) <= (bufaddr+buflen))
808 memcpy(myaddr, &readbuf[memaddr-bufaddr], len);
817 if ((startaddr % 16) != 0)
818 len_this_pass -= startaddr % 16;
819 if (len_this_pass > (len - count))
820 len_this_pass = (len - count);
822 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
824 printf_monitor (MEM_DIS_CMD, startaddr, 8);
826 for (i = 0; i < 16; i++)
828 get_hex_byte (&readbuf[i]);
832 memcpy(&myaddr[count], readbuf, len_this_pass);
833 count += len_this_pass;
834 startaddr += len_this_pass;
835 expect(CMD_DELIM, 1);
838 printf_monitor (CMD_END);
845 /* FIXME-someday! merge these two. */
847 rombug_xfer_inferior_memory (memaddr, myaddr, len, write, target)
852 struct target_ops *target; /* ignored */
855 return rombug_write_inferior_memory (memaddr, myaddr, len);
857 return rombug_read_inferior_memory (memaddr, myaddr, len);
861 rombug_kill (args, from_tty)
865 return; /* ignore attempts to kill target system */
868 /* Clean up when a program exits.
869 The program actually lives on in the remote processor's RAM, and may be
870 run again without a download. Don't leave it full of breakpoint
874 rombug_mourn_inferior ()
876 remove_breakpoints ();
877 generic_mourn_inferior (); /* Do all the proper things now */
880 #define MAX_MONITOR_BREAKPOINTS 16
882 extern int memory_breakpoint_size;
883 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
886 rombug_insert_breakpoint (addr, shadow)
893 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
895 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
896 if (breakaddr[i] == 0)
900 printf ("Breakpoint at %x\n", addr);
901 rombug_read_inferior_memory(addr, shadow, memory_breakpoint_size);
902 printf_monitor(SET_BREAK_CMD, addr);
908 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
913 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
916 rombug_remove_breakpoint (addr, shadow)
923 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
925 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
926 if (breakaddr[i] == addr)
929 printf_monitor(CLR_BREAK_CMD, addr);
935 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
939 /* Load a file. This is usually an srecord, which is ascii. No
940 protocol, just sent line by line. */
942 #define DOWNLOAD_LINE_SIZE 100
947 /* this part comment out for os9* */
950 char buf[DOWNLOAD_LINE_SIZE];
954 printf ("Loading %s to monitor\n", arg);
956 download = fopen (arg, "r");
957 if (download == NULL)
959 error (sprintf (buf, "%s Does not exist", arg));
963 printf_monitor (LOAD_CMD);
964 /* expect ("Waiting for S-records from host... ", 1); */
966 while (!feof (download))
968 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
975 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
976 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
980 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
981 if (bytes_read < DOWNLOAD_LINE_SIZE)
983 if (!feof (download))
984 error ("Only read %d bytes\n", bytes_read);
993 if (!feof (download))
994 error ("Never got EOF while downloading");
999 /* Put a command string, in args, out to MONITOR.
1000 Output from MONITOR is placed on the users terminal until the prompt
1004 rombug_command (args, fromtty)
1008 if (monitor_desc == NULL)
1009 error("monitor target not open.");
1012 fprintf (log_file, "\nIn command (args=%s)\n", args);
1015 error("Missing command.");
1017 printf_monitor("%s\r", args);
1022 /* Connect the user directly to MONITOR. This command acts just like the
1023 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1025 static struct ttystate ttystate;
1029 { printf("\r\n[Exiting connect mode]\r\n");
1030 /*SERIAL_RESTORE(0, &ttystate);*/
1034 connect_command (args, fromtty)
1045 if (monitor_desc == NULL)
1046 error("monitor target not open.");
1049 fprintf("This command takes no args. They have been ignored.\n");
1051 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
1053 serial_raw(0, &ttystate);
1055 make_cleanup(cleanup_tty, 0);
1063 FD_SET(0, &readfds);
1064 FD_SET(monitor_desc, &readfds);
1065 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1067 while (numfds == 0);
1070 perror_with_name("select");
1072 if (FD_ISSET(0, &readfds))
1073 { /* tty input, send to monitor */
1076 perror_with_name("connect");
1078 printf_monitor("%c", c);
1092 if (c == '.' || c == '\004')
1099 if (FD_ISSET(monitor_desc, &readfds))
1115 * Define the monitor command strings. Since these are passed directly
1116 * through to a printf style function, we need can include formatting
1117 * strings. We also need a CR or LF on the end.
1119 struct monitor_ops rombug_cmds = {
1120 "g \r", /* execute or usually GO command */
1121 "g \r", /* continue command */
1122 "t \r", /* single step */
1123 "b %x\r", /* set a breakpoint */
1124 "k %x\r", /* clear a breakpoint */
1125 "c %x\r", /* set memory to a value */
1126 "d %x %d\r", /* display memory */
1127 "$%08X", /* prompt memory commands use */
1128 ".%s %x\r", /* set a register */
1129 ":", /* delimiter between registers */
1130 ". \r", /* read a register */
1131 "mf \r", /* download command */
1132 "RomBug: ", /* monitor command prompt */
1133 ": ", /* end-of-command delimitor */
1134 ".\r" /* optional command terminator */
1137 struct target_ops rombug_ops = {
1139 "Microware's ROMBUG debug monitor",
1140 "Use a remote computer running the ROMBUG debug monitor.\n\
1141 Specify the serial device it is connected to (e.g. /dev/ttya).",
1148 rombug_fetch_register,
1149 rombug_store_register,
1150 rombug_prepare_to_store,
1151 rombug_xfer_inferior_memory,
1153 rombug_insert_breakpoint,
1154 rombug_remove_breakpoint, /* Breakpoints */
1159 0, /* Terminal handling */
1161 rombug_load, /* load */
1162 rombug_link, /* lookup_symbol */
1163 rombug_create_inferior,
1164 rombug_mourn_inferior,
1166 0, /* notice_signals */
1173 1, /* has execution */
1175 0, /* Section pointers */
1176 OPS_MAGIC, /* Always the last thing */
1180 _initialize_remote_os9k ()
1182 add_target (&rombug_ops);
1185 add_set_cmd ("hash", no_class, var_boolean, (char *)&hashmark,
1186 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1191 add_set_cmd ("timeout", no_class, var_zinteger,
1193 "Set timeout in seconds for remote MIPS serial I/O.",
1198 add_set_cmd ("remotelog", no_class, var_zinteger,
1199 (char *) &monitor_log,
1200 "Set monitor activity log on(=1) or off(=0).",
1205 add_set_cmd ("remotexon", no_class, var_zinteger,
1207 "Set remote tty line XON control",
1212 add_set_cmd ("remotexoff", no_class, var_zinteger,
1214 "Set remote tty line XOFF control",
1218 add_com ("rombug <command>", class_obscure, rombug_command,
1219 "Send a command to the debug monitor.");
1221 add_com ("connect", class_obscure, connect_command,
1222 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");