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