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"
53 struct monitor_ops *current_monitor;
54 struct cmd_list_element *showlist;
55 extern struct target_ops rombug_ops; /* Forward declaration */
56 extern struct monitor_ops rombug_cmds; /* Forward declaration */
57 extern struct cmd_list_element *setlist;
58 extern struct cmd_list_element *unsetlist;
59 extern int attach_flag;
61 static void rombug_close();
62 static void rombug_fetch_register();
63 static void rombug_fetch_registers();
64 static void rombug_store_register();
66 static int sr_get_debug(); /* flag set by "set remotedebug" */
68 static int hashmark; /* flag set by "set hash" */
69 static int rombug_is_open = 0;
71 /* FIXME: Replace with sr_get_debug (). */
72 #define LOG_FILE "monitor.log"
74 static int monitor_log = 0;
75 static int tty_xon = 0;
76 static int tty_xoff = 0;
78 static int timeout = 10;
79 static int is_trace_mode = 0;
80 /* Descriptor for I/O to remote machine. Initialize it to NULL*/
81 static serial_t monitor_desc = NULL;
83 static CORE_ADDR bufaddr = 0;
84 static int buflen = 0;
85 static char readbuf[16];
87 /* Send data to monitor. Works just like printf. */
89 printf_monitor(va_alist)
99 pattern = va_arg(args, char *);
101 vsprintf(buf, pattern, args);
103 if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
104 fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
107 /* Read a character from the remote system, doing all the fancy timeout stuff*/
114 c = SERIAL_READCHAR(monitor_desc, timeout);
119 if (monitor_log && isascii(c))
120 putc(c & 0x7f, log_file);
125 if (c == SERIAL_TIMEOUT)
128 return c; /* Polls shouldn't generate timeout errors */
130 error("Timeout reading from remote system.");
133 perror_with_name("remote-monitor");
136 /* Scan input from the remote system, until STRING is found. If DISCARD is
137 non-zero, then discard non-matching input, else print it out.
138 Let the user break out immediately. */
140 expect(string, discard)
148 printf ("Expecting \"%s\"\n", string);
153 c = readchar(timeout);
162 printf ("\nMatched\n");
170 fwrite(string, 1, (p - 1) - string, stdout);
179 /* Keep discarding input until we see the ROMBUG prompt.
181 The convention for dealing with the prompt is that you
183 o *then* wait for the prompt.
185 Thus the last thing that a procedure does with the serial line
186 will be an expect_prompt(). Exception: rombug_resume does not
187 wait for the prompt, because the terminal is being handed over
188 to the inferior. However, the next thing which happens after that
189 is a rombug_wait which does wait for the prompt.
190 Note that this includes abnormal exit, e.g. error(). This is
191 necessary to prevent getting into states from which we can't
194 expect_prompt(discard)
198 /* This is a convenient place to do this. The idea is to do it often
199 enough that we never lose much data if we terminate abnormally. */
203 expect("trace", discard);
205 expect (PROMPT, discard);
209 /* Get a hex digit from the remote system & return its value.
210 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
212 get_hex_digit(ignore_space)
218 ch = readchar(timeout);
219 if (ch >= '0' && ch <= '9')
221 else if (ch >= 'A' && ch <= 'F')
222 return ch - 'A' + 10;
223 else if (ch >= 'a' && ch <= 'f')
224 return ch - 'a' + 10;
225 else if (ch == ' ' && ignore_space)
230 error("Invalid hex digit from remote system.");
235 /* Get a byte from monitor and put it in *BYT. Accept any number
243 val = get_hex_digit (1) << 4;
244 val |= get_hex_digit (0);
248 /* Get N 32-bit words from remote, each preceded by a space,
249 and put them in registers starting at REGNO. */
251 get_hex_regs (n, regno)
259 for (i = 0; i < n; i++)
264 for (j = 0; j < 4; j++)
267 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
268 val = (val << 8) + b;
270 val = val + (b << (j*8));
272 supply_register (regno++, (char *) &val);
276 /* This is called not only when we first attach, but also when the
277 user types "run" after having attached. */
279 rombug_create_inferior (execfile, args, env)
287 error("Can't pass arguments to remote ROMBUG process");
289 if (execfile == 0 || exec_bfd == 0)
290 error("No exec file specified");
292 entry_pt = (int) bfd_get_start_address (exec_bfd);
295 fputs ("\nIn Create_inferior()", log_file);
298 /* The "process" (board) is already stopped awaiting our commands, and
299 the program is already downloaded. We just set its PC and go. */
301 init_wait_for_inferior ();
302 proceed ((CORE_ADDR)entry_pt, TARGET_SIGNAL_DEFAULT, 0);
305 /* Open a connection to a remote debugger.
306 NAME is the filename used for communication. */
308 static char dev_name[100];
311 rombug_open(args, from_tty)
316 error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
317 `target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
319 target_preopen(from_tty);
322 unpush_target(&rombug_ops);
324 strcpy(dev_name, args);
325 monitor_desc = SERIAL_OPEN(dev_name);
326 if (monitor_desc == NULL)
327 perror_with_name(dev_name);
329 /* if baud rate is set by 'set remotebaud' */
330 if (SERIAL_SETBAUDRATE (monitor_desc, sr_get_baud_rate()))
332 SERIAL_CLOSE (monitor_desc);
333 perror_with_name ("RomBug");
335 SERIAL_RAW(monitor_desc);
336 if (tty_xon || tty_xoff)
338 struct hardware_ttystate { struct termios t;} *tty_s;
340 tty_s =(struct hardware_ttystate *)SERIAL_GET_TTY_STATE(monitor_desc);
341 if (tty_xon) tty_s->t.c_iflag |= IXON;
342 if (tty_xoff) tty_s->t.c_iflag |= IXOFF;
343 SERIAL_SET_TTY_STATE(monitor_desc, (serial_ttystate) tty_s);
348 log_file = fopen (LOG_FILE, "w");
349 if (log_file == NULL)
350 perror_with_name (LOG_FILE);
352 push_monitor (&rombug_cmds);
353 printf_monitor("\r"); /* CR wakes up monitor */
355 push_target (&rombug_ops);
359 printf("Remote %s connected to %s\n", target_shortname,
362 rombug_fetch_registers();
364 printf_monitor ("ov e \r");
371 * Close out all files and local state before this target loses control.
375 rombug_close (quitting)
378 if (rombug_is_open) {
379 SERIAL_CLOSE(monitor_desc);
385 if (ferror(log_file))
386 fprintf(stderr, "Error writing log file.\n");
387 if (fclose(log_file) != 0)
388 fprintf(stderr, "Error closing log file.\n");
394 rombug_link(mod_name, text_reloc)
396 CORE_ADDR *text_reloc;
402 printf_monitor("l %s \r", mod_name);
404 printf_monitor(".r \r");
405 expect(REG_DELIM, 1);
406 for (i=0; i <= 7; i++)
409 for (j = 0; j < 4; j++)
412 val = (val << 8) + b;
420 /* Terminate the open connection to the remote debugger.
421 Use this when you want to detach and do something else
424 rombug_detach (from_tty)
428 printf_monitor (GO_CMD);
431 pop_target(); /* calls rombug_close to do the real work */
433 printf ("Ending remote %s debugging\n", target_shortname);
437 * Tell the remote machine to resume.
440 rombug_resume (pid, step, sig)
442 enum target_signal sig;
445 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
450 printf_monitor (STEP_CMD);
451 /* wait for the echo. **
452 expect (STEP_CMD, 1);
457 printf_monitor (GO_CMD);
458 /* swallow the echo. **
467 * Wait until the remote machine stops, then return,
468 * storing status in status just as `wait' would.
472 rombug_wait (pid, status)
474 struct target_waitstatus *status;
476 int old_timeout = timeout;
477 struct section_offsets *offs;
479 struct obj_section *obj_sec;
482 fputs ("\nIn wait ()", log_file);
484 status->kind = TARGET_WAITKIND_EXITED;
485 status->value.integer = 0;
487 timeout = -1; /* Don't time out -- user program is running. */
488 expect ("eax:", 0); /* output any message before register display */
489 expect_prompt(1); /* Wait for prompt, outputting extraneous text */
491 status->kind = TARGET_WAITKIND_STOPPED;
492 status->value.sig = TARGET_SIGNAL_TRAP;
493 timeout = old_timeout;
494 rombug_fetch_registers();
497 pc = read_register(PC_REGNUM);
498 addr = read_register(DATABASE_REG);
499 obj_sec = find_pc_section (pc);
502 if (obj_sec->objfile != symfile_objfile)
503 new_symfile_objfile(obj_sec->objfile, 1, 0);
504 offs = ((struct section_offsets *)
505 alloca (sizeof (struct section_offsets)
506 + (symfile_objfile->num_sections * sizeof (offs->offsets))));
507 memcpy (offs, symfile_objfile->section_offsets,
508 (sizeof (struct section_offsets) +
509 (symfile_objfile->num_sections * sizeof (offs->offsets))));
510 ANOFFSET (offs, SECT_OFF_DATA) = addr;
511 ANOFFSET (offs, SECT_OFF_BSS) = addr;
513 objfile_relocate(symfile_objfile, offs);
519 /* Return the name of register number regno in the form input and output by
520 monitor. Currently, register_names just happens to contain exactly what
521 monitor wants. Lets take advantage of that just as long as possible! */
536 for (p = reg_names[regno]; *p; p++)
540 p = (char *)reg_names[regno];
547 /* read the remote registers into the block regs. */
550 rombug_fetch_registers ()
556 printf_monitor (GET_REG);
567 for (regno = 8; regno <= 15; regno++)
569 expect(REG_DELIM, 1);
570 if (regno >= 8 && regno <= 13)
573 for (j = 0; j < 2; j++)
576 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
577 val = (val << 8) + b;
579 val = val + (b << (j*8));
582 if (regno == 8) i = 10;
583 if (regno >= 9 && regno <= 12) i = regno + 3;
584 if (regno == 13) i = 11;
585 supply_register (i, (char *) &val);
587 else if (regno == 14)
589 get_hex_regs(1, PC_REGNUM);
591 else if (regno == 15)
598 supply_register(regno, (char *) &val);
605 /* Fetch register REGNO, or all registers if REGNO is -1.
606 Returns errno value. */
608 rombug_fetch_register (regno)
615 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
621 rombug_fetch_registers ();
625 char *name = get_reg_name (regno);
626 printf_monitor (GET_REG);
627 if (regno >= 10 && regno <= 15)
632 expect (REG_DELIM, 1);
634 for (j = 0; j < 2; j++)
637 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
638 val = (val << 8) + b;
640 val = val + (b << (j*8));
642 supply_register (regno, (char *) &val);
644 else if (regno == 8 || regno == 9)
650 expect (REG_DELIM, 1);
651 get_hex_regs (1, regno);
656 expect (REG_DELIM, 1);
672 /* Store the remote registers from the contents of the block REGS. */
675 rombug_store_registers ()
679 for (regno = 0; regno <= PC_REGNUM; regno++)
680 rombug_store_register(regno);
682 registers_changed ();
685 /* Store register REGNO, or all if REGNO == 0.
686 return errno value. */
688 rombug_store_register (regno)
694 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
697 rombug_store_registers ();
701 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
703 name = get_reg_name(regno);
704 if (name == 0) return;
705 printf_monitor (SET_REG, name, read_register (regno));
712 /* Get ready to modify the registers array. On machines which store
713 individual registers, this doesn't need to do anything. On machines
714 which store all the registers in one fell swoop, this makes sure
715 that registers contains all the registers from the program being
719 rombug_prepare_to_store ()
721 /* Do nothing, since we can store individual regs */
727 printf ("\tAttached to %s at %d baud.\n",
728 dev_name, sr_get_baud_rate());
731 /* Copy LEN bytes of data from debugger memory at MYADDR
732 to inferior's memory at MEMADDR. Returns length moved. */
734 rombug_write_inferior_memory (memaddr, myaddr, len)
736 unsigned char *myaddr;
743 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
745 printf_monitor (MEM_SET_CMD, memaddr);
746 for (i = 0; i < len; i++)
748 expect (CMD_DELIM, 1);
749 printf_monitor ("%x \r", myaddr[i]);
751 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
753 expect (CMD_DELIM, 1);
755 printf_monitor (CMD_END);
764 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
765 at debugger address MYADDR. Returns length moved. */
767 rombug_read_inferior_memory(memaddr, myaddr, len)
774 /* Number of bytes read so far. */
777 /* Starting address of this pass. */
778 unsigned long startaddr;
780 /* Number of bytes to read in this pass. */
784 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
786 /* Note that this code works correctly if startaddr is just less
787 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
788 thing). That is, something like
789 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
790 works--it never adds len To memaddr and gets 0. */
791 /* However, something like
792 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
793 doesn't need to work. Detect it and give up if there's an attempt
795 if (((memaddr - 1) + len) < memaddr) {
799 if (bufaddr <= memaddr && (memaddr+len) <= (bufaddr+buflen))
801 memcpy(myaddr, &readbuf[memaddr-bufaddr], len);
810 if ((startaddr % 16) != 0)
811 len_this_pass -= startaddr % 16;
812 if (len_this_pass > (len - count))
813 len_this_pass = (len - count);
815 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
817 printf_monitor (MEM_DIS_CMD, startaddr, 8);
819 for (i = 0; i < 16; i++)
821 get_hex_byte (&readbuf[i]);
825 memcpy(&myaddr[count], readbuf, len_this_pass);
826 count += len_this_pass;
827 startaddr += len_this_pass;
828 expect(CMD_DELIM, 1);
831 printf_monitor (CMD_END);
838 /* FIXME-someday! merge these two. */
840 rombug_xfer_inferior_memory (memaddr, myaddr, len, write, target)
845 struct target_ops *target; /* ignored */
848 return rombug_write_inferior_memory (memaddr, myaddr, len);
850 return rombug_read_inferior_memory (memaddr, myaddr, len);
854 rombug_kill (args, from_tty)
858 return; /* ignore attempts to kill target system */
861 /* Clean up when a program exits.
862 The program actually lives on in the remote processor's RAM, and may be
863 run again without a download. Don't leave it full of breakpoint
867 rombug_mourn_inferior ()
869 remove_breakpoints ();
870 generic_mourn_inferior (); /* Do all the proper things now */
873 #define MAX_MONITOR_BREAKPOINTS 16
875 extern int memory_breakpoint_size;
876 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
879 rombug_insert_breakpoint (addr, shadow)
886 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
888 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
889 if (breakaddr[i] == 0)
893 printf ("Breakpoint at %x\n", addr);
894 rombug_read_inferior_memory(addr, shadow, memory_breakpoint_size);
895 printf_monitor(SET_BREAK_CMD, addr);
901 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
906 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
909 rombug_remove_breakpoint (addr, shadow)
916 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
918 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
919 if (breakaddr[i] == addr)
922 printf_monitor(CLR_BREAK_CMD, addr);
928 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
932 /* Load a file. This is usually an srecord, which is ascii. No
933 protocol, just sent line by line. */
935 #define DOWNLOAD_LINE_SIZE 100
940 /* this part comment out for os9* */
943 char buf[DOWNLOAD_LINE_SIZE];
947 printf ("Loading %s to monitor\n", arg);
949 download = fopen (arg, "r");
950 if (download == NULL)
952 error (sprintf (buf, "%s Does not exist", arg));
956 printf_monitor (LOAD_CMD);
957 /* expect ("Waiting for S-records from host... ", 1); */
959 while (!feof (download))
961 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
968 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
969 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
973 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
974 if (bytes_read < DOWNLOAD_LINE_SIZE)
976 if (!feof (download))
977 error ("Only read %d bytes\n", bytes_read);
986 if (!feof (download))
987 error ("Never got EOF while downloading");
992 /* Put a command string, in args, out to MONITOR.
993 Output from MONITOR is placed on the users terminal until the prompt
997 rombug_command (args, fromtty)
1001 if (monitor_desc == NULL)
1002 error("monitor target not open.");
1005 fprintf (log_file, "\nIn command (args=%s)\n", args);
1008 error("Missing command.");
1010 printf_monitor("%s\r", args);
1015 /* Connect the user directly to MONITOR. This command acts just like the
1016 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1018 static struct ttystate ttystate;
1022 { printf("\r\n[Exiting connect mode]\r\n");
1023 /*SERIAL_RESTORE(0, &ttystate);*/
1027 connect_command (args, fromtty)
1038 if (monitor_desc == NULL)
1039 error("monitor target not open.");
1042 fprintf("This command takes no args. They have been ignored.\n");
1044 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
1046 serial_raw(0, &ttystate);
1048 make_cleanup(cleanup_tty, 0);
1056 FD_SET(0, &readfds);
1057 FD_SET(monitor_desc, &readfds);
1058 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1060 while (numfds == 0);
1063 perror_with_name("select");
1065 if (FD_ISSET(0, &readfds))
1066 { /* tty input, send to monitor */
1069 perror_with_name("connect");
1071 printf_monitor("%c", c);
1085 if (c == '.' || c == '\004')
1092 if (FD_ISSET(monitor_desc, &readfds))
1108 * Define the monitor command strings. Since these are passed directly
1109 * through to a printf style function, we need can include formatting
1110 * strings. We also need a CR or LF on the end.
1112 struct monitor_ops rombug_cmds = {
1113 "g \r", /* execute or usually GO command */
1114 "g \r", /* continue command */
1115 "t \r", /* single step */
1116 "b %x\r", /* set a breakpoint */
1117 "k %x\r", /* clear a breakpoint */
1118 "c %x\r", /* set memory to a value */
1119 "d %x %d\r", /* display memory */
1120 "$%08X", /* prompt memory commands use */
1121 ".%s %x\r", /* set a register */
1122 ":", /* delimiter between registers */
1123 ". \r", /* read a register */
1124 "mf \r", /* download command */
1125 "RomBug: ", /* monitor command prompt */
1126 ": ", /* end-of-command delimitor */
1127 ".\r" /* optional command terminator */
1130 struct target_ops rombug_ops = {
1132 "Microware's ROMBUG debug monitor",
1133 "Use a remote computer running the ROMBUG debug monitor.\n\
1134 Specify the serial device it is connected to (e.g. /dev/ttya).",
1141 rombug_fetch_register,
1142 rombug_store_register,
1143 rombug_prepare_to_store,
1144 rombug_xfer_inferior_memory,
1146 rombug_insert_breakpoint,
1147 rombug_remove_breakpoint, /* Breakpoints */
1152 0, /* Terminal handling */
1154 rombug_load, /* load */
1155 rombug_link, /* lookup_symbol */
1156 rombug_create_inferior,
1157 rombug_mourn_inferior,
1159 0, /* notice_signals */
1167 1, /* has execution */
1169 0, /* Section pointers */
1170 OPS_MAGIC, /* Always the last thing */
1174 _initialize_remote_os9k ()
1176 add_target (&rombug_ops);
1179 add_set_cmd ("hash", no_class, var_boolean, (char *)&hashmark,
1180 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1185 add_set_cmd ("timeout", no_class, var_zinteger,
1187 "Set timeout in seconds for remote MIPS serial I/O.",
1192 add_set_cmd ("remotelog", no_class, var_zinteger,
1193 (char *) &monitor_log,
1194 "Set monitor activity log on(=1) or off(=0).",
1199 add_set_cmd ("remotexon", no_class, var_zinteger,
1201 "Set remote tty line XON control",
1206 add_set_cmd ("remotexoff", no_class, var_zinteger,
1208 "Set remote tty line XOFF control",
1212 add_com ("rombug <command>", class_obscure, rombug_command,
1213 "Send a command to the debug monitor.");
1215 add_com ("connect", class_obscure, connect_command,
1216 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");