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