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