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