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