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