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