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