]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/remote-os9k.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / remote-os9k.c
1 /* Remote debugging interface for boot monitors, for GDB.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, 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 a different situation--
26 having a PC running os9000 hook up with a unix machine with
27 a serial line, and running ctty com2 on the PC. os9000 has a debug
28 monitor called ROMBUG running. 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 'ROMBUG', which
33 We communicate with ROMBUG via a direct serial line, the network version
34 of ROMBUG is not available yet.
35 */
36
37 /* FIXME This file needs to be rewritten if it's to work again, either
38 to self-contained or to use the new monitor interface. */
39
40 #include "defs.h"
41 #include "gdbcore.h"
42 #include "target.h"
43 #include "wait.h"
44 #ifdef ANSI_PROTOTYPES
45 #include <stdarg.h>
46 #else
47 #include <varargs.h>
48 #endif
49 #include <signal.h>
50 #include "gdb_string.h"
51 #include <sys/types.h>
52 #include "command.h"
53 #include "serial.h"
54 #include "monitor.h"
55 #include "remote-utils.h"
56 #include "symtab.h"
57 #include "symfile.h"
58 #include "objfiles.h"
59 #include "gdb-stabs.h"
60
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;
67
68 static void rombug_close ();
69 static void rombug_fetch_register ();
70 static void rombug_fetch_registers ();
71 static void rombug_store_register ();
72 #if 0
73 static int sr_get_debug (); /* flag set by "set remotedebug" */
74 #endif
75 static int hashmark; /* flag set by "set hash" */
76 static int rombug_is_open = 0;
77
78 /* FIXME: Replace with sr_get_debug (). */
79 #define LOG_FILE "monitor.log"
80 FILE *log_file;
81 static int monitor_log = 0;
82 static int tty_xon = 0;
83 static int tty_xoff = 0;
84
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;
89
90 static CORE_ADDR bufaddr = 0;
91 static int buflen = 0;
92 static char readbuf[16];
93
94 /* Send data to monitor. Works just like printf. */
95 static void
96 #ifdef ANSI_PROTOTYPES
97 printf_monitor (char *pattern,...)
98 #else
99 printf_monitor (va_alist)
100 va_dcl
101 #endif
102 {
103 va_list args;
104 char buf[200];
105 int i;
106
107 #ifdef ANSI_PROTOTYPES
108 va_start (args, pattern);
109 #else
110 char *pattern;
111 va_start (args);
112 pattern = va_arg (args, char *);
113 #endif
114
115 vsprintf (buf, pattern, args);
116 va_end (args);
117
118 if (SERIAL_WRITE (monitor_desc, buf, strlen (buf)))
119 fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
120 }
121
122 /* Read a character from the remote system, doing all the fancy timeout stuff */
123 static int
124 readchar (timeout)
125 int timeout;
126 {
127 int c;
128
129 c = SERIAL_READCHAR (monitor_desc, timeout);
130
131 if (sr_get_debug ())
132 putchar (c & 0x7f);
133
134 if (monitor_log && isascii (c))
135 putc (c & 0x7f, log_file);
136
137 if (c >= 0)
138 return c & 0x7f;
139
140 if (c == SERIAL_TIMEOUT)
141 {
142 if (timeout == 0)
143 return c; /* Polls shouldn't generate timeout errors */
144
145 error ("Timeout reading from remote system.");
146 }
147
148 perror_with_name ("remote-monitor");
149 }
150
151 /* Scan input from the remote system, until STRING is found. If DISCARD is
152 non-zero, then discard non-matching input, else print it out.
153 Let the user break out immediately. */
154 static void
155 expect (string, discard)
156 char *string;
157 int discard;
158 {
159 char *p = string;
160 int c;
161
162 if (sr_get_debug ())
163 printf ("Expecting \"%s\"\n", string);
164
165 immediate_quit = 1;
166 while (1)
167 {
168 c = readchar (timeout);
169 if (!isascii (c))
170 continue;
171 if (c == *p++)
172 {
173 if (*p == '\0')
174 {
175 immediate_quit = 0;
176 if (sr_get_debug ())
177 printf ("\nMatched\n");
178 return;
179 }
180 }
181 else
182 {
183 if (!discard)
184 {
185 fwrite (string, 1, (p - 1) - string, stdout);
186 putchar ((char) c);
187 fflush (stdout);
188 }
189 p = string;
190 }
191 }
192 }
193
194 /* Keep discarding input until we see the ROMBUG prompt.
195
196 The convention for dealing with the prompt is that you
197 o give your command
198 o *then* wait for the prompt.
199
200 Thus the last thing that a procedure does with the serial line
201 will be an expect_prompt(). Exception: rombug_resume does not
202 wait for the prompt, because the terminal is being handed over
203 to the inferior. However, the next thing which happens after that
204 is a rombug_wait which does wait for the prompt.
205 Note that this includes abnormal exit, e.g. error(). This is
206 necessary to prevent getting into states from which we can't
207 recover. */
208 static void
209 expect_prompt (discard)
210 int discard;
211 {
212 if (monitor_log)
213 /* This is a convenient place to do this. The idea is to do it often
214 enough that we never lose much data if we terminate abnormally. */
215 fflush (log_file);
216
217 if (is_trace_mode)
218 {
219 expect ("trace", discard);
220 }
221 else
222 {
223 expect (PROMPT, discard);
224 }
225 }
226
227 /* Get a hex digit from the remote system & return its value.
228 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
229 static int
230 get_hex_digit (ignore_space)
231 int ignore_space;
232 {
233 int ch;
234 while (1)
235 {
236 ch = readchar (timeout);
237 if (ch >= '0' && ch <= '9')
238 return ch - '0';
239 else if (ch >= 'A' && ch <= 'F')
240 return ch - 'A' + 10;
241 else if (ch >= 'a' && ch <= 'f')
242 return ch - 'a' + 10;
243 else if (ch == ' ' && ignore_space)
244 ;
245 else
246 {
247 expect_prompt (1);
248 error ("Invalid hex digit from remote system.");
249 }
250 }
251 }
252
253 /* Get a byte from monitor and put it in *BYT. Accept any number
254 leading spaces. */
255 static void
256 get_hex_byte (byt)
257 char *byt;
258 {
259 int val;
260
261 val = get_hex_digit (1) << 4;
262 val |= get_hex_digit (0);
263 *byt = val;
264 }
265
266 /* Get N 32-bit words from remote, each preceded by a space,
267 and put them in registers starting at REGNO. */
268 static void
269 get_hex_regs (n, regno)
270 int n;
271 int regno;
272 {
273 long val;
274 int i;
275 unsigned char b;
276
277 for (i = 0; i < n; i++)
278 {
279 int j;
280
281 val = 0;
282 for (j = 0; j < 4; j++)
283 {
284 get_hex_byte (&b);
285 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
286 val = (val << 8) + b;
287 else
288 val = val + (b << (j * 8));
289 }
290 supply_register (regno++, (char *) &val);
291 }
292 }
293
294 /* This is called not only when we first attach, but also when the
295 user types "run" after having attached. */
296 static void
297 rombug_create_inferior (execfile, args, env)
298 char *execfile;
299 char *args;
300 char **env;
301 {
302 int entry_pt;
303
304 if (args && *args)
305 error ("Can't pass arguments to remote ROMBUG process");
306
307 if (execfile == 0 || exec_bfd == 0)
308 error ("No executable file specified");
309
310 entry_pt = (int) bfd_get_start_address (exec_bfd);
311
312 if (monitor_log)
313 fputs ("\nIn Create_inferior()", log_file);
314
315
316 /* The "process" (board) is already stopped awaiting our commands, and
317 the program is already downloaded. We just set its PC and go. */
318
319 init_wait_for_inferior ();
320 proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
321 }
322
323 /* Open a connection to a remote debugger.
324 NAME is the filename used for communication. */
325
326 static char dev_name[100];
327
328 static void
329 rombug_open (args, from_tty)
330 char *args;
331 int from_tty;
332 {
333 if (args == NULL)
334 error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
335 `target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
336
337 target_preopen (from_tty);
338
339 if (rombug_is_open)
340 unpush_target (&rombug_ops);
341
342 strcpy (dev_name, args);
343 monitor_desc = SERIAL_OPEN (dev_name);
344 if (monitor_desc == NULL)
345 perror_with_name (dev_name);
346
347 /* if baud rate is set by 'set remotebaud' */
348 if (SERIAL_SETBAUDRATE (monitor_desc, sr_get_baud_rate ()))
349 {
350 SERIAL_CLOSE (monitor_desc);
351 perror_with_name ("RomBug");
352 }
353 SERIAL_RAW (monitor_desc);
354 if (tty_xon || tty_xoff)
355 {
356 struct hardware_ttystate
357 {
358 struct termios t;
359 }
360 *tty_s;
361
362 tty_s = (struct hardware_ttystate *) SERIAL_GET_TTY_STATE (monitor_desc);
363 if (tty_xon)
364 tty_s->t.c_iflag |= IXON;
365 if (tty_xoff)
366 tty_s->t.c_iflag |= IXOFF;
367 SERIAL_SET_TTY_STATE (monitor_desc, (serial_ttystate) tty_s);
368 }
369
370 rombug_is_open = 1;
371
372 log_file = fopen (LOG_FILE, "w");
373 if (log_file == NULL)
374 perror_with_name (LOG_FILE);
375
376 push_monitor (&rombug_cmds);
377 printf_monitor ("\r"); /* CR wakes up monitor */
378 expect_prompt (1);
379 push_target (&rombug_ops);
380 attach_flag = 1;
381
382 if (from_tty)
383 printf ("Remote %s connected to %s\n", target_shortname,
384 dev_name);
385
386 rombug_fetch_registers ();
387
388 printf_monitor ("ov e \r");
389 expect_prompt (1);
390 bufaddr = 0;
391 buflen = 0;
392 }
393
394 /*
395 * Close out all files and local state before this target loses control.
396 */
397
398 static void
399 rombug_close (quitting)
400 int quitting;
401 {
402 if (rombug_is_open)
403 {
404 SERIAL_CLOSE (monitor_desc);
405 monitor_desc = NULL;
406 rombug_is_open = 0;
407 }
408
409 if (log_file)
410 {
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 log_file = 0;
416 }
417 }
418
419 int
420 rombug_link (mod_name, text_reloc)
421 char *mod_name;
422 CORE_ADDR *text_reloc;
423 {
424 int i, j;
425 unsigned long val;
426 unsigned char b;
427
428 printf_monitor ("l %s \r", mod_name);
429 expect_prompt (1);
430 printf_monitor (".r \r");
431 expect (REG_DELIM, 1);
432 for (i = 0; i <= 7; i++)
433 {
434 val = 0;
435 for (j = 0; j < 4; j++)
436 {
437 get_hex_byte (&b);
438 val = (val << 8) + b;
439 }
440 }
441 expect_prompt (1);
442 *text_reloc = val;
443 return 1;
444 }
445
446 /* Terminate the open connection to the remote debugger.
447 Use this when you want to detach and do something else
448 with your gdb. */
449 static void
450 rombug_detach (from_tty)
451 int from_tty;
452 {
453 if (attach_flag)
454 {
455 printf_monitor (GO_CMD);
456 attach_flag = 0;
457 }
458 pop_target (); /* calls rombug_close to do the real work */
459 if (from_tty)
460 printf ("Ending remote %s debugging\n", target_shortname);
461 }
462
463 /*
464 * Tell the remote machine to resume.
465 */
466 static void
467 rombug_resume (pid, step, sig)
468 int pid, step;
469 enum target_signal sig;
470 {
471 if (monitor_log)
472 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
473
474 if (step)
475 {
476 is_trace_mode = 1;
477 printf_monitor (STEP_CMD);
478 /* wait for the echo. **
479 expect (STEP_CMD, 1);
480 */
481 }
482 else
483 {
484 printf_monitor (GO_CMD);
485 /* swallow the echo. **
486 expect (GO_CMD, 1);
487 */
488 }
489 bufaddr = 0;
490 buflen = 0;
491 }
492
493 /*
494 * Wait until the remote machine stops, then return,
495 * storing status in status just as `wait' would.
496 */
497
498 static int
499 rombug_wait (pid, status)
500 int pid;
501 struct target_waitstatus *status;
502 {
503 int old_timeout = timeout;
504 struct section_offsets *offs;
505 CORE_ADDR addr, pc;
506 struct obj_section *obj_sec;
507
508 if (monitor_log)
509 fputs ("\nIn wait ()", log_file);
510
511 status->kind = TARGET_WAITKIND_EXITED;
512 status->value.integer = 0;
513
514 timeout = -1; /* Don't time out -- user program is running. */
515 expect ("eax:", 0); /* output any message before register display */
516 expect_prompt (1); /* Wait for prompt, outputting extraneous text */
517
518 status->kind = TARGET_WAITKIND_STOPPED;
519 status->value.sig = TARGET_SIGNAL_TRAP;
520 timeout = old_timeout;
521 rombug_fetch_registers ();
522 bufaddr = 0;
523 buflen = 0;
524 pc = read_register (PC_REGNUM);
525 addr = read_register (DATABASE_REG);
526 obj_sec = find_pc_section (pc);
527 if (obj_sec != NULL)
528 {
529 if (obj_sec->objfile != symfile_objfile)
530 new_symfile_objfile (obj_sec->objfile, 1, 0);
531 offs = ((struct section_offsets *)
532 alloca (sizeof (struct section_offsets)
533 + (symfile_objfile->num_sections * sizeof (offs->offsets))));
534 memcpy (offs, symfile_objfile->section_offsets,
535 (sizeof (struct section_offsets) +
536 (symfile_objfile->num_sections * sizeof (offs->offsets))));
537 ANOFFSET (offs, SECT_OFF_DATA) = addr;
538 ANOFFSET (offs, SECT_OFF_BSS) = addr;
539
540 objfile_relocate (symfile_objfile, offs);
541 }
542
543 return 0;
544 }
545
546 /* Return the name of register number regno in the form input and output by
547 monitor. Currently, register_names just happens to contain exactly what
548 monitor wants. Lets take advantage of that just as long as possible! */
549
550 static char *
551 get_reg_name (regno)
552 int regno;
553 {
554 static char buf[50];
555 char *p;
556 char *b;
557
558 b = buf;
559
560 if (regno < 0)
561 return ("");
562 /*
563 for (p = REGISTER_NAME (regno); *p; p++)
564 *b++ = toupper(*p);
565 *b = '\000';
566 */
567 p = (char *) REGISTER_NAME (regno);
568 return p;
569 /*
570 return buf;
571 */
572 }
573
574 /* read the remote registers into the block regs. */
575
576 static void
577 rombug_fetch_registers ()
578 {
579 int regno, j, i;
580 long val;
581 unsigned char b;
582
583 printf_monitor (GET_REG);
584 expect ("eax:", 1);
585 expect ("\n", 1);
586 get_hex_regs (1, 0);
587 get_hex_regs (1, 3);
588 get_hex_regs (1, 1);
589 get_hex_regs (1, 2);
590 get_hex_regs (1, 6);
591 get_hex_regs (1, 7);
592 get_hex_regs (1, 5);
593 get_hex_regs (1, 4);
594 for (regno = 8; regno <= 15; regno++)
595 {
596 expect (REG_DELIM, 1);
597 if (regno >= 8 && regno <= 13)
598 {
599 val = 0;
600 for (j = 0; j < 2; j++)
601 {
602 get_hex_byte (&b);
603 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
604 val = (val << 8) + b;
605 else
606 val = val + (b << (j * 8));
607 }
608
609 if (regno == 8)
610 i = 10;
611 if (regno >= 9 && regno <= 12)
612 i = regno + 3;
613 if (regno == 13)
614 i = 11;
615 supply_register (i, (char *) &val);
616 }
617 else if (regno == 14)
618 {
619 get_hex_regs (1, PC_REGNUM);
620 }
621 else if (regno == 15)
622 {
623 get_hex_regs (1, 9);
624 }
625 else
626 {
627 val = 0;
628 supply_register (regno, (char *) &val);
629 }
630 }
631 is_trace_mode = 0;
632 expect_prompt (1);
633 }
634
635 /* Fetch register REGNO, or all registers if REGNO is -1.
636 Returns errno value. */
637 static void
638 rombug_fetch_register (regno)
639 int regno;
640 {
641 int val, j;
642 unsigned char b;
643
644 if (monitor_log)
645 {
646 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
647 fflush (log_file);
648 }
649
650 if (regno < 0)
651 {
652 rombug_fetch_registers ();
653 }
654 else
655 {
656 char *name = get_reg_name (regno);
657 printf_monitor (GET_REG);
658 if (regno >= 10 && regno <= 15)
659 {
660 expect ("\n", 1);
661 expect ("\n", 1);
662 expect (name, 1);
663 expect (REG_DELIM, 1);
664 val = 0;
665 for (j = 0; j < 2; j++)
666 {
667 get_hex_byte (&b);
668 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
669 val = (val << 8) + b;
670 else
671 val = val + (b << (j * 8));
672 }
673 supply_register (regno, (char *) &val);
674 }
675 else if (regno == 8 || regno == 9)
676 {
677 expect ("\n", 1);
678 expect ("\n", 1);
679 expect ("\n", 1);
680 expect (name, 1);
681 expect (REG_DELIM, 1);
682 get_hex_regs (1, regno);
683 }
684 else
685 {
686 expect (name, 1);
687 expect (REG_DELIM, 1);
688 expect ("\n", 1);
689 get_hex_regs (1, 0);
690 get_hex_regs (1, 3);
691 get_hex_regs (1, 1);
692 get_hex_regs (1, 2);
693 get_hex_regs (1, 6);
694 get_hex_regs (1, 7);
695 get_hex_regs (1, 5);
696 get_hex_regs (1, 4);
697 }
698 expect_prompt (1);
699 }
700 return;
701 }
702
703 /* Store the remote registers from the contents of the block REGS. */
704
705 static void
706 rombug_store_registers ()
707 {
708 int regno;
709
710 for (regno = 0; regno <= PC_REGNUM; regno++)
711 rombug_store_register (regno);
712
713 registers_changed ();
714 }
715
716 /* Store register REGNO, or all if REGNO == 0.
717 return errno value. */
718 static void
719 rombug_store_register (regno)
720 int regno;
721 {
722 char *name;
723
724 if (monitor_log)
725 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
726
727 if (regno == -1)
728 rombug_store_registers ();
729 else
730 {
731 if (sr_get_debug ())
732 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
733
734 name = get_reg_name (regno);
735 if (name == 0)
736 return;
737 printf_monitor (SET_REG, name, read_register (regno));
738
739 is_trace_mode = 0;
740 expect_prompt (1);
741 }
742 }
743
744 /* Get ready to modify the registers array. On machines which store
745 individual registers, this doesn't need to do anything. On machines
746 which store all the registers in one fell swoop, this makes sure
747 that registers contains all the registers from the program being
748 debugged. */
749
750 static void
751 rombug_prepare_to_store ()
752 {
753 /* Do nothing, since we can store individual regs */
754 }
755
756 static void
757 rombug_files_info ()
758 {
759 printf ("\tAttached to %s at %d baud.\n",
760 dev_name, sr_get_baud_rate ());
761 }
762
763 /* Copy LEN bytes of data from debugger memory at MYADDR
764 to inferior's memory at MEMADDR. Returns length moved. */
765 static int
766 rombug_write_inferior_memory (memaddr, myaddr, len)
767 CORE_ADDR memaddr;
768 unsigned char *myaddr;
769 int len;
770 {
771 int i;
772 char buf[10];
773
774 if (monitor_log)
775 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
776
777 printf_monitor (MEM_SET_CMD, memaddr);
778 for (i = 0; i < len; i++)
779 {
780 expect (CMD_DELIM, 1);
781 printf_monitor ("%x \r", myaddr[i]);
782 if (sr_get_debug ())
783 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
784 }
785 expect (CMD_DELIM, 1);
786 if (CMD_END)
787 printf_monitor (CMD_END);
788 is_trace_mode = 0;
789 expect_prompt (1);
790
791 bufaddr = 0;
792 buflen = 0;
793 return len;
794 }
795
796 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
797 at debugger address MYADDR. Returns length moved. */
798 static int
799 rombug_read_inferior_memory (memaddr, myaddr, len)
800 CORE_ADDR memaddr;
801 char *myaddr;
802 int len;
803 {
804 int i, j;
805
806 /* Number of bytes read so far. */
807 int count;
808
809 /* Starting address of this pass. */
810 unsigned long startaddr;
811
812 /* Number of bytes to read in this pass. */
813 int len_this_pass;
814
815 if (monitor_log)
816 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
817
818 /* Note that this code works correctly if startaddr is just less
819 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
820 thing). That is, something like
821 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
822 works--it never adds len To memaddr and gets 0. */
823 /* However, something like
824 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
825 doesn't need to work. Detect it and give up if there's an attempt
826 to do that. */
827 if (((memaddr - 1) + len) < memaddr)
828 {
829 errno = EIO;
830 return 0;
831 }
832 if (bufaddr <= memaddr && (memaddr + len) <= (bufaddr + buflen))
833 {
834 memcpy (myaddr, &readbuf[memaddr - bufaddr], len);
835 return len;
836 }
837
838 startaddr = memaddr;
839 count = 0;
840 while (count < len)
841 {
842 len_this_pass = 16;
843 if ((startaddr % 16) != 0)
844 len_this_pass -= startaddr % 16;
845 if (len_this_pass > (len - count))
846 len_this_pass = (len - count);
847 if (sr_get_debug ())
848 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
849
850 printf_monitor (MEM_DIS_CMD, startaddr, 8);
851 expect ("- ", 1);
852 for (i = 0; i < 16; i++)
853 {
854 get_hex_byte (&readbuf[i]);
855 }
856 bufaddr = startaddr;
857 buflen = 16;
858 memcpy (&myaddr[count], readbuf, len_this_pass);
859 count += len_this_pass;
860 startaddr += len_this_pass;
861 expect (CMD_DELIM, 1);
862 }
863 if (CMD_END)
864 printf_monitor (CMD_END);
865 is_trace_mode = 0;
866 expect_prompt (1);
867
868 return len;
869 }
870
871 /* FIXME-someday! merge these two. */
872 static int
873 rombug_xfer_inferior_memory (memaddr, myaddr, len, write, target)
874 CORE_ADDR memaddr;
875 char *myaddr;
876 int len;
877 int write;
878 struct target_ops *target; /* ignored */
879 {
880 if (write)
881 return rombug_write_inferior_memory (memaddr, myaddr, len);
882 else
883 return rombug_read_inferior_memory (memaddr, myaddr, len);
884 }
885
886 static void
887 rombug_kill (args, from_tty)
888 char *args;
889 int from_tty;
890 {
891 return; /* ignore attempts to kill target system */
892 }
893
894 /* Clean up when a program exits.
895 The program actually lives on in the remote processor's RAM, and may be
896 run again without a download. Don't leave it full of breakpoint
897 instructions. */
898
899 static void
900 rombug_mourn_inferior ()
901 {
902 remove_breakpoints ();
903 generic_mourn_inferior (); /* Do all the proper things now */
904 }
905
906 #define MAX_MONITOR_BREAKPOINTS 16
907
908 static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] =
909 {0};
910
911 static int
912 rombug_insert_breakpoint (addr, shadow)
913 CORE_ADDR addr;
914 char *shadow;
915 {
916 int i;
917 CORE_ADDR bp_addr = addr;
918 int bp_size = 0;
919
920 if (monitor_log)
921 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
922 BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
923
924 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
925 if (breakaddr[i] == 0)
926 {
927 breakaddr[i] = addr;
928 if (sr_get_debug ())
929 printf ("Breakpoint at %x\n", addr);
930 rombug_read_inferior_memory (bp_addr, shadow, bp_size);
931 printf_monitor (SET_BREAK_CMD, addr);
932 is_trace_mode = 0;
933 expect_prompt (1);
934 return 0;
935 }
936
937 fprintf (stderr, "Too many breakpoints (> 16) for monitor\n");
938 return 1;
939 }
940
941 /*
942 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
943 */
944 static int
945 rombug_remove_breakpoint (addr, shadow)
946 CORE_ADDR addr;
947 char *shadow;
948 {
949 int i;
950
951 if (monitor_log)
952 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
953
954 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
955 if (breakaddr[i] == addr)
956 {
957 breakaddr[i] = 0;
958 printf_monitor (CLR_BREAK_CMD, addr);
959 is_trace_mode = 0;
960 expect_prompt (1);
961 return 0;
962 }
963
964 fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
965 return 1;
966 }
967
968 /* Load a file. This is usually an srecord, which is ascii. No
969 protocol, just sent line by line. */
970
971 #define DOWNLOAD_LINE_SIZE 100
972 static void
973 rombug_load (arg)
974 char *arg;
975 {
976 /* this part comment out for os9* */
977 #if 0
978 FILE *download;
979 char buf[DOWNLOAD_LINE_SIZE];
980 int i, bytes_read;
981
982 if (sr_get_debug ())
983 printf ("Loading %s to monitor\n", arg);
984
985 download = fopen (arg, "r");
986 if (download == NULL)
987 {
988 error (sprintf (buf, "%s Does not exist", arg));
989 return;
990 }
991
992 printf_monitor (LOAD_CMD);
993 /* expect ("Waiting for S-records from host... ", 1); */
994
995 while (!feof (download))
996 {
997 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
998 if (hashmark)
999 {
1000 putchar ('.');
1001 fflush (stdout);
1002 }
1003
1004 if (SERIAL_WRITE (monitor_desc, buf, bytes_read))
1005 {
1006 fprintf (stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror (errno));
1007 break;
1008 }
1009 i = 0;
1010 while (i++ <= 200000)
1011 {
1012 }; /* Ugly HACK, probably needs flow control */
1013 if (bytes_read < DOWNLOAD_LINE_SIZE)
1014 {
1015 if (!feof (download))
1016 error ("Only read %d bytes\n", bytes_read);
1017 break;
1018 }
1019 }
1020
1021 if (hashmark)
1022 {
1023 putchar ('\n');
1024 }
1025 if (!feof (download))
1026 error ("Never got EOF while downloading");
1027 fclose (download);
1028 #endif /* 0 */
1029 }
1030
1031 /* Put a command string, in args, out to MONITOR.
1032 Output from MONITOR is placed on the users terminal until the prompt
1033 is seen. */
1034
1035 static void
1036 rombug_command (args, fromtty)
1037 char *args;
1038 int fromtty;
1039 {
1040 if (monitor_desc == NULL)
1041 error ("monitor target not open.");
1042
1043 if (monitor_log)
1044 fprintf (log_file, "\nIn command (args=%s)\n", args);
1045
1046 if (!args)
1047 error ("Missing command.");
1048
1049 printf_monitor ("%s\r", args);
1050 expect_prompt (0);
1051 }
1052
1053 #if 0
1054 /* Connect the user directly to MONITOR. This command acts just like the
1055 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1056
1057 static struct ttystate ttystate;
1058
1059 static void
1060 cleanup_tty ()
1061 {
1062 printf ("\r\n[Exiting connect mode]\r\n");
1063 /*SERIAL_RESTORE(0, &ttystate); */
1064 }
1065
1066 static void
1067 connect_command (args, fromtty)
1068 char *args;
1069 int fromtty;
1070 {
1071 fd_set readfds;
1072 int numfds;
1073 int c;
1074 char cur_esc = 0;
1075
1076 dont_repeat ();
1077
1078 if (monitor_desc == NULL)
1079 error ("monitor target not open.");
1080
1081 if (args)
1082 fprintf ("This command takes no args. They have been ignored.\n");
1083
1084 printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
1085
1086 serial_raw (0, &ttystate);
1087
1088 make_cleanup (cleanup_tty, 0);
1089
1090 FD_ZERO (&readfds);
1091
1092 while (1)
1093 {
1094 do
1095 {
1096 FD_SET (0, &readfds);
1097 FD_SET (monitor_desc, &readfds);
1098 numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
1099 }
1100 while (numfds == 0);
1101
1102 if (numfds < 0)
1103 perror_with_name ("select");
1104
1105 if (FD_ISSET (0, &readfds))
1106 { /* tty input, send to monitor */
1107 c = getchar ();
1108 if (c < 0)
1109 perror_with_name ("connect");
1110
1111 printf_monitor ("%c", c);
1112 switch (cur_esc)
1113 {
1114 case 0:
1115 if (c == '\r')
1116 cur_esc = c;
1117 break;
1118 case '\r':
1119 if (c == '~')
1120 cur_esc = c;
1121 else
1122 cur_esc = 0;
1123 break;
1124 case '~':
1125 if (c == '.' || c == '\004')
1126 return;
1127 else
1128 cur_esc = 0;
1129 }
1130 }
1131
1132 if (FD_ISSET (monitor_desc, &readfds))
1133 {
1134 while (1)
1135 {
1136 c = readchar (0);
1137 if (c < 0)
1138 break;
1139 putchar (c);
1140 }
1141 fflush (stdout);
1142 }
1143 }
1144 }
1145 #endif
1146
1147 /*
1148 * Define the monitor command strings. Since these are passed directly
1149 * through to a printf style function, we need can include formatting
1150 * strings. We also need a CR or LF on the end.
1151 */
1152 #warning FIXME: monitor interface pattern strings, stale struct decl
1153 struct monitor_ops rombug_cmds =
1154 {
1155 "g \r", /* execute or usually GO command */
1156 "g \r", /* continue command */
1157 "t \r", /* single step */
1158 "b %x\r", /* set a breakpoint */
1159 "k %x\r", /* clear a breakpoint */
1160 "c %x\r", /* set memory to a value */
1161 "d %x %d\r", /* display memory */
1162 "$%08X", /* prompt memory commands use */
1163 ".%s %x\r", /* set a register */
1164 ":", /* delimiter between registers */
1165 ". \r", /* read a register */
1166 "mf \r", /* download command */
1167 "RomBug: ", /* monitor command prompt */
1168 ": ", /* end-of-command delimitor */
1169 ".\r" /* optional command terminator */
1170 };
1171
1172 struct target_ops rombug_ops;
1173
1174 static void
1175 init_rombug_ops (void)
1176 {
1177 rombug_ops.to_shortname = "rombug";
1178 rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
1179 rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
1180 Specify the serial device it is connected to (e.g. /dev/ttya).",
1181 rombug_ops.to_open = rombug_open;
1182 rombug_ops.to_close = rombug_close;
1183 rombug_ops.to_attach = 0;
1184 rombug_ops.to_post_attach = NULL;
1185 rombug_ops.to_require_attach = NULL;
1186 rombug_ops.to_detach = rombug_detach;
1187 rombug_ops.to_require_detach = NULL;
1188 rombug_ops.to_resume = rombug_resume;
1189 rombug_ops.to_wait = rombug_wait;
1190 rombug_ops.to_post_wait = NULL;
1191 rombug_ops.to_fetch_registers = rombug_fetch_register;
1192 rombug_ops.to_store_registers = rombug_store_register;
1193 rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
1194 rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
1195 rombug_ops.to_files_info = rombug_files_info;
1196 rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
1197 rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
1198 rombug_ops.to_terminal_init = 0;
1199 rombug_ops.to_terminal_inferior = 0;
1200 rombug_ops.to_terminal_ours_for_output = 0;
1201 rombug_ops.to_terminal_ours = 0;
1202 rombug_ops.to_terminal_info = 0; /* Terminal handling */
1203 rombug_ops.to_kill = rombug_kill;
1204 rombug_ops.to_load = rombug_load; /* load */
1205 rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
1206 rombug_ops.to_create_inferior = rombug_create_inferior;
1207 rombug_ops.to_post_startup_inferior = NULL;
1208 rombug_ops.to_acknowledge_created_inferior = NULL;
1209 rombug_ops.to_clone_and_follow_inferior = NULL;
1210 rombug_ops.to_post_follow_inferior_by_clone = NULL;
1211 rombug_ops.to_insert_fork_catchpoint = NULL;
1212 rombug_ops.to_remove_fork_catchpoint = NULL;
1213 rombug_ops.to_insert_vfork_catchpoint = NULL;
1214 rombug_ops.to_remove_vfork_catchpoint = NULL;
1215 rombug_ops.to_has_forked = NULL;
1216 rombug_ops.to_has_vforked = NULL;
1217 rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
1218 rombug_ops.to_post_follow_vfork = NULL;
1219 rombug_ops.to_insert_exec_catchpoint = NULL;
1220 rombug_ops.to_remove_exec_catchpoint = NULL;
1221 rombug_ops.to_has_execd = NULL;
1222 rombug_ops.to_reported_exec_events_per_exec_call = NULL;
1223 rombug_ops.to_has_exited = NULL;
1224 rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
1225 rombug_ops.to_can_run = 0; /* can_run */
1226 rombug_ops.to_notice_signals = 0; /* notice_signals */
1227 rombug_ops.to_thread_alive = 0;
1228 rombug_ops.to_stop = 0; /* to_stop */
1229 rombug_ops.to_pid_to_exec_file = NULL;
1230 rombug_ops.to_core_file_to_sym_file = NULL;
1231 rombug_ops.to_stratum = process_stratum;
1232 rombug_ops.DONT_USE = 0; /* next */
1233 rombug_ops.to_has_all_memory = 1;
1234 rombug_ops.to_has_memory = 1;
1235 rombug_ops.to_has_stack = 1;
1236 rombug_ops.to_has_registers = 1;
1237 rombug_ops.to_has_execution = 1; /* has execution */
1238 rombug_ops.to_sections = 0;
1239 rombug_ops.to_sections_end = 0; /* Section pointers */
1240 rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
1241 }
1242
1243 void
1244 _initialize_remote_os9k ()
1245 {
1246 init_rombug_ops ();
1247 add_target (&rombug_ops);
1248
1249 add_show_from_set (
1250 add_set_cmd ("hash", no_class, var_boolean, (char *) &hashmark,
1251 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1252 &setlist),
1253 &showlist);
1254
1255 add_show_from_set (
1256 add_set_cmd ("timeout", no_class, var_zinteger,
1257 (char *) &timeout,
1258 "Set timeout in seconds for remote MIPS serial I/O.",
1259 &setlist),
1260 &showlist);
1261
1262 add_show_from_set (
1263 add_set_cmd ("remotelog", no_class, var_zinteger,
1264 (char *) &monitor_log,
1265 "Set monitor activity log on(=1) or off(=0).",
1266 &setlist),
1267 &showlist);
1268
1269 add_show_from_set (
1270 add_set_cmd ("remotexon", no_class, var_zinteger,
1271 (char *) &tty_xon,
1272 "Set remote tty line XON control",
1273 &setlist),
1274 &showlist);
1275
1276 add_show_from_set (
1277 add_set_cmd ("remotexoff", no_class, var_zinteger,
1278 (char *) &tty_xoff,
1279 "Set remote tty line XOFF control",
1280 &setlist),
1281 &showlist);
1282
1283 add_com ("rombug <command>", class_obscure, rombug_command,
1284 "Send a command to the debug monitor.");
1285 #if 0
1286 add_com ("connect", class_obscure, connect_command,
1287 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
1288 #endif
1289 }