import gdb-1999-09-21
[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);
d4f3574e
SS
515 offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
516 memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
c906108c
SS
517 ANOFFSET (offs, SECT_OFF_DATA) = addr;
518 ANOFFSET (offs, SECT_OFF_BSS) = addr;
519
c5aa993b 520 objfile_relocate (symfile_objfile, offs);
c906108c
SS
521 }
522
523 return 0;
524}
525
526/* Return the name of register number regno in the form input and output by
527 monitor. Currently, register_names just happens to contain exactly what
528 monitor wants. Lets take advantage of that just as long as possible! */
529
530static char *
531get_reg_name (regno)
532 int regno;
533{
534 static char buf[50];
535 char *p;
536 char *b;
537
538 b = buf;
539
540 if (regno < 0)
541 return ("");
542/*
c5aa993b
JM
543 for (p = REGISTER_NAME (regno); *p; p++)
544 *b++ = toupper(*p);
545 *b = '\000';
546 */
547 p = (char *) REGISTER_NAME (regno);
c906108c
SS
548 return p;
549/*
c5aa993b
JM
550 return buf;
551 */
c906108c
SS
552}
553
554/* read the remote registers into the block regs. */
555
556static void
557rombug_fetch_registers ()
558{
559 int regno, j, i;
560 long val;
561 unsigned char b;
562
563 printf_monitor (GET_REG);
c5aa993b
JM
564 expect ("eax:", 1);
565 expect ("\n", 1);
566 get_hex_regs (1, 0);
567 get_hex_regs (1, 3);
568 get_hex_regs (1, 1);
569 get_hex_regs (1, 2);
570 get_hex_regs (1, 6);
571 get_hex_regs (1, 7);
572 get_hex_regs (1, 5);
573 get_hex_regs (1, 4);
c906108c
SS
574 for (regno = 8; regno <= 15; regno++)
575 {
c5aa993b 576 expect (REG_DELIM, 1);
c906108c
SS
577 if (regno >= 8 && regno <= 13)
578 {
579 val = 0;
580 for (j = 0; j < 2; j++)
c5aa993b
JM
581 {
582 get_hex_byte (&b);
c906108c
SS
583 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
584 val = (val << 8) + b;
585 else
c5aa993b
JM
586 val = val + (b << (j * 8));
587 }
c906108c 588
c5aa993b
JM
589 if (regno == 8)
590 i = 10;
591 if (regno >= 9 && regno <= 12)
592 i = regno + 3;
593 if (regno == 13)
594 i = 11;
c906108c
SS
595 supply_register (i, (char *) &val);
596 }
597 else if (regno == 14)
598 {
c5aa993b 599 get_hex_regs (1, PC_REGNUM);
c906108c
SS
600 }
601 else if (regno == 15)
602 {
c5aa993b 603 get_hex_regs (1, 9);
c906108c
SS
604 }
605 else
606 {
607 val = 0;
c5aa993b 608 supply_register (regno, (char *) &val);
c906108c
SS
609 }
610 }
611 is_trace_mode = 0;
612 expect_prompt (1);
613}
614
615/* Fetch register REGNO, or all registers if REGNO is -1.
616 Returns errno value. */
617static void
618rombug_fetch_register (regno)
619 int regno;
620{
621 int val, j;
622 unsigned char b;
623
c5aa993b
JM
624 if (monitor_log)
625 {
626 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
627 fflush (log_file);
628 }
c906108c
SS
629
630 if (regno < 0)
631 {
632 rombug_fetch_registers ();
633 }
634 else
635 {
636 char *name = get_reg_name (regno);
637 printf_monitor (GET_REG);
638 if (regno >= 10 && regno <= 15)
639 {
640 expect ("\n", 1);
641 expect ("\n", 1);
c5aa993b
JM
642 expect (name, 1);
643 expect (REG_DELIM, 1);
c906108c
SS
644 val = 0;
645 for (j = 0; j < 2; j++)
c5aa993b
JM
646 {
647 get_hex_byte (&b);
c906108c
SS
648 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
649 val = (val << 8) + b;
650 else
c5aa993b
JM
651 val = val + (b << (j * 8));
652 }
c906108c
SS
653 supply_register (regno, (char *) &val);
654 }
655 else if (regno == 8 || regno == 9)
656 {
657 expect ("\n", 1);
658 expect ("\n", 1);
659 expect ("\n", 1);
c5aa993b
JM
660 expect (name, 1);
661 expect (REG_DELIM, 1);
c906108c
SS
662 get_hex_regs (1, regno);
663 }
664 else
665 {
c5aa993b
JM
666 expect (name, 1);
667 expect (REG_DELIM, 1);
668 expect ("\n", 1);
669 get_hex_regs (1, 0);
670 get_hex_regs (1, 3);
671 get_hex_regs (1, 1);
672 get_hex_regs (1, 2);
673 get_hex_regs (1, 6);
674 get_hex_regs (1, 7);
675 get_hex_regs (1, 5);
676 get_hex_regs (1, 4);
c906108c
SS
677 }
678 expect_prompt (1);
679 }
680 return;
681}
682
683/* Store the remote registers from the contents of the block REGS. */
684
685static void
686rombug_store_registers ()
687{
688 int regno;
689
690 for (regno = 0; regno <= PC_REGNUM; regno++)
c5aa993b 691 rombug_store_register (regno);
c906108c
SS
692
693 registers_changed ();
694}
695
696/* Store register REGNO, or all if REGNO == 0.
697 return errno value. */
698static void
699rombug_store_register (regno)
700 int regno;
701{
c5aa993b 702 char *name;
c906108c
SS
703
704 if (monitor_log)
705 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
706
707 if (regno == -1)
708 rombug_store_registers ();
709 else
710 {
c5aa993b 711 if (sr_get_debug ())
c906108c
SS
712 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
713
c5aa993b
JM
714 name = get_reg_name (regno);
715 if (name == 0)
716 return;
c906108c
SS
717 printf_monitor (SET_REG, name, read_register (regno));
718
719 is_trace_mode = 0;
720 expect_prompt (1);
721 }
722}
723
724/* Get ready to modify the registers array. On machines which store
725 individual registers, this doesn't need to do anything. On machines
726 which store all the registers in one fell swoop, this makes sure
727 that registers contains all the registers from the program being
728 debugged. */
729
730static void
731rombug_prepare_to_store ()
732{
733 /* Do nothing, since we can store individual regs */
734}
735
736static void
737rombug_files_info ()
738{
739 printf ("\tAttached to %s at %d baud.\n",
c5aa993b 740 dev_name, sr_get_baud_rate ());
c906108c
SS
741}
742
743/* Copy LEN bytes of data from debugger memory at MYADDR
744 to inferior's memory at MEMADDR. Returns length moved. */
745static int
746rombug_write_inferior_memory (memaddr, myaddr, len)
747 CORE_ADDR memaddr;
748 unsigned char *myaddr;
749 int len;
750{
751 int i;
752 char buf[10];
753
754 if (monitor_log)
755 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
756
757 printf_monitor (MEM_SET_CMD, memaddr);
758 for (i = 0; i < len; i++)
759 {
760 expect (CMD_DELIM, 1);
761 printf_monitor ("%x \r", myaddr[i]);
c5aa993b 762 if (sr_get_debug ())
c906108c
SS
763 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
764 }
765 expect (CMD_DELIM, 1);
766 if (CMD_END)
767 printf_monitor (CMD_END);
768 is_trace_mode = 0;
769 expect_prompt (1);
770
771 bufaddr = 0;
772 buflen = 0;
773 return len;
774}
775
776/* Read LEN bytes from inferior memory at MEMADDR. Put the result
777 at debugger address MYADDR. Returns length moved. */
778static int
c5aa993b 779rombug_read_inferior_memory (memaddr, myaddr, len)
c906108c
SS
780 CORE_ADDR memaddr;
781 char *myaddr;
782 int len;
783{
784 int i, j;
785
786 /* Number of bytes read so far. */
787 int count;
788
789 /* Starting address of this pass. */
790 unsigned long startaddr;
791
792 /* Number of bytes to read in this pass. */
793 int len_this_pass;
794
795 if (monitor_log)
796 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
797
798 /* Note that this code works correctly if startaddr is just less
799 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
800 thing). That is, something like
801 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
802 works--it never adds len To memaddr and gets 0. */
803 /* However, something like
804 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
805 doesn't need to work. Detect it and give up if there's an attempt
806 to do that. */
c5aa993b
JM
807 if (((memaddr - 1) + len) < memaddr)
808 {
809 errno = EIO;
810 return 0;
811 }
812 if (bufaddr <= memaddr && (memaddr + len) <= (bufaddr + buflen))
c906108c 813 {
c5aa993b 814 memcpy (myaddr, &readbuf[memaddr - bufaddr], len);
c906108c
SS
815 return len;
816 }
c5aa993b 817
c906108c
SS
818 startaddr = memaddr;
819 count = 0;
820 while (count < len)
821 {
822 len_this_pass = 16;
823 if ((startaddr % 16) != 0)
824 len_this_pass -= startaddr % 16;
825 if (len_this_pass > (len - count))
826 len_this_pass = (len - count);
c5aa993b 827 if (sr_get_debug ())
c906108c
SS
828 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
829
830 printf_monitor (MEM_DIS_CMD, startaddr, 8);
831 expect ("- ", 1);
832 for (i = 0; i < 16; i++)
833 {
834 get_hex_byte (&readbuf[i]);
835 }
836 bufaddr = startaddr;
837 buflen = 16;
c5aa993b 838 memcpy (&myaddr[count], readbuf, len_this_pass);
c906108c
SS
839 count += len_this_pass;
840 startaddr += len_this_pass;
c5aa993b 841 expect (CMD_DELIM, 1);
c906108c 842 }
c5aa993b
JM
843 if (CMD_END)
844 printf_monitor (CMD_END);
c906108c
SS
845 is_trace_mode = 0;
846 expect_prompt (1);
847
848 return len;
849}
850
851/* FIXME-someday! merge these two. */
852static int
853rombug_xfer_inferior_memory (memaddr, myaddr, len, write, target)
854 CORE_ADDR memaddr;
855 char *myaddr;
856 int len;
857 int write;
c5aa993b 858 struct target_ops *target; /* ignored */
c906108c
SS
859{
860 if (write)
861 return rombug_write_inferior_memory (memaddr, myaddr, len);
862 else
863 return rombug_read_inferior_memory (memaddr, myaddr, len);
864}
865
866static void
867rombug_kill (args, from_tty)
868 char *args;
869 int from_tty;
870{
c5aa993b 871 return; /* ignore attempts to kill target system */
c906108c
SS
872}
873
874/* Clean up when a program exits.
875 The program actually lives on in the remote processor's RAM, and may be
876 run again without a download. Don't leave it full of breakpoint
877 instructions. */
878
879static void
880rombug_mourn_inferior ()
881{
882 remove_breakpoints ();
883 generic_mourn_inferior (); /* Do all the proper things now */
884}
885
886#define MAX_MONITOR_BREAKPOINTS 16
887
c5aa993b
JM
888static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] =
889{0};
c906108c
SS
890
891static int
892rombug_insert_breakpoint (addr, shadow)
893 CORE_ADDR addr;
894 char *shadow;
895{
896 int i;
897 CORE_ADDR bp_addr = addr;
898 int bp_size = 0;
899
900 if (monitor_log)
901 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
902 BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
903
904 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
905 if (breakaddr[i] == 0)
906 {
907 breakaddr[i] = addr;
c5aa993b 908 if (sr_get_debug ())
c906108c
SS
909 printf ("Breakpoint at %x\n", addr);
910 rombug_read_inferior_memory (bp_addr, shadow, bp_size);
c5aa993b 911 printf_monitor (SET_BREAK_CMD, addr);
c906108c 912 is_trace_mode = 0;
c5aa993b 913 expect_prompt (1);
c906108c
SS
914 return 0;
915 }
916
c5aa993b 917 fprintf (stderr, "Too many breakpoints (> 16) for monitor\n");
c906108c
SS
918 return 1;
919}
920
921/*
922 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
923 */
924static int
925rombug_remove_breakpoint (addr, shadow)
926 CORE_ADDR addr;
927 char *shadow;
928{
929 int i;
930
931 if (monitor_log)
932 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
933
934 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
935 if (breakaddr[i] == addr)
936 {
937 breakaddr[i] = 0;
c5aa993b 938 printf_monitor (CLR_BREAK_CMD, addr);
c906108c 939 is_trace_mode = 0;
c5aa993b 940 expect_prompt (1);
c906108c
SS
941 return 0;
942 }
943
c5aa993b 944 fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
c906108c
SS
945 return 1;
946}
947
948/* Load a file. This is usually an srecord, which is ascii. No
949 protocol, just sent line by line. */
950
951#define DOWNLOAD_LINE_SIZE 100
952static void
953rombug_load (arg)
c5aa993b 954 char *arg;
c906108c
SS
955{
956/* this part comment out for os9* */
957#if 0
958 FILE *download;
959 char buf[DOWNLOAD_LINE_SIZE];
960 int i, bytes_read;
961
c5aa993b 962 if (sr_get_debug ())
c906108c
SS
963 printf ("Loading %s to monitor\n", arg);
964
965 download = fopen (arg, "r");
966 if (download == NULL)
967 {
c5aa993b
JM
968 error (sprintf (buf, "%s Does not exist", arg));
969 return;
970 }
c906108c
SS
971
972 printf_monitor (LOAD_CMD);
973/* expect ("Waiting for S-records from host... ", 1); */
974
975 while (!feof (download))
976 {
977 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
978 if (hashmark)
979 {
980 putchar ('.');
981 fflush (stdout);
982 }
983
c5aa993b
JM
984 if (SERIAL_WRITE (monitor_desc, buf, bytes_read))
985 {
986 fprintf (stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror (errno));
987 break;
988 }
c906108c 989 i = 0;
c5aa993b
JM
990 while (i++ <= 200000)
991 {
992 }; /* Ugly HACK, probably needs flow control */
c906108c
SS
993 if (bytes_read < DOWNLOAD_LINE_SIZE)
994 {
995 if (!feof (download))
996 error ("Only read %d bytes\n", bytes_read);
997 break;
998 }
999 }
1000
1001 if (hashmark)
1002 {
1003 putchar ('\n');
1004 }
1005 if (!feof (download))
1006 error ("Never got EOF while downloading");
1007 fclose (download);
c5aa993b 1008#endif /* 0 */
c906108c
SS
1009}
1010
1011/* Put a command string, in args, out to MONITOR.
1012 Output from MONITOR is placed on the users terminal until the prompt
1013 is seen. */
1014
1015static void
1016rombug_command (args, fromtty)
c5aa993b
JM
1017 char *args;
1018 int fromtty;
c906108c
SS
1019{
1020 if (monitor_desc == NULL)
c5aa993b
JM
1021 error ("monitor target not open.");
1022
c906108c
SS
1023 if (monitor_log)
1024 fprintf (log_file, "\nIn command (args=%s)\n", args);
1025
1026 if (!args)
c5aa993b
JM
1027 error ("Missing command.");
1028
1029 printf_monitor ("%s\r", args);
1030 expect_prompt (0);
c906108c
SS
1031}
1032
1033#if 0
1034/* Connect the user directly to MONITOR. This command acts just like the
1035 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1036
1037static struct ttystate ttystate;
1038
1039static void
c5aa993b
JM
1040cleanup_tty ()
1041{
1042 printf ("\r\n[Exiting connect mode]\r\n");
1043 /*SERIAL_RESTORE(0, &ttystate); */
c906108c
SS
1044}
1045
1046static void
1047connect_command (args, fromtty)
c5aa993b
JM
1048 char *args;
1049 int fromtty;
c906108c
SS
1050{
1051 fd_set readfds;
1052 int numfds;
1053 int c;
1054 char cur_esc = 0;
1055
c5aa993b 1056 dont_repeat ();
c906108c
SS
1057
1058 if (monitor_desc == NULL)
c5aa993b
JM
1059 error ("monitor target not open.");
1060
c906108c 1061 if (args)
c5aa993b
JM
1062 fprintf ("This command takes no args. They have been ignored.\n");
1063
1064 printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
c906108c 1065
c5aa993b 1066 serial_raw (0, &ttystate);
c906108c 1067
c5aa993b 1068 make_cleanup (cleanup_tty, 0);
c906108c 1069
c5aa993b 1070 FD_ZERO (&readfds);
c906108c
SS
1071
1072 while (1)
1073 {
1074 do
1075 {
c5aa993b 1076 FD_SET (0, &readfds);
c2c6d25f 1077 FD_SET (DEPRECATED_SERIAL_FD (monitor_desc), &readfds);
c5aa993b 1078 numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
c906108c
SS
1079 }
1080 while (numfds == 0);
1081
1082 if (numfds < 0)
c5aa993b 1083 perror_with_name ("select");
c906108c 1084
c5aa993b 1085 if (FD_ISSET (0, &readfds))
c906108c 1086 { /* tty input, send to monitor */
c5aa993b 1087 c = getchar ();
c906108c 1088 if (c < 0)
c5aa993b 1089 perror_with_name ("connect");
c906108c 1090
c5aa993b 1091 printf_monitor ("%c", c);
c906108c
SS
1092 switch (cur_esc)
1093 {
1094 case 0:
1095 if (c == '\r')
1096 cur_esc = c;
1097 break;
1098 case '\r':
1099 if (c == '~')
1100 cur_esc = c;
1101 else
1102 cur_esc = 0;
1103 break;
1104 case '~':
1105 if (c == '.' || c == '\004')
1106 return;
1107 else
1108 cur_esc = 0;
1109 }
1110 }
1111
c2c6d25f 1112 if (FD_ISSET (DEPRECATED_SERIAL_FD (monitor_desc), &readfds))
c906108c
SS
1113 {
1114 while (1)
1115 {
c5aa993b 1116 c = readchar (0);
c906108c
SS
1117 if (c < 0)
1118 break;
c5aa993b 1119 putchar (c);
c906108c 1120 }
c5aa993b 1121 fflush (stdout);
c906108c
SS
1122 }
1123 }
1124}
1125#endif
1126
1127/*
1128 * Define the monitor command strings. Since these are passed directly
1129 * through to a printf style function, we need can include formatting
1130 * strings. We also need a CR or LF on the end.
1131 */
1132#warning FIXME: monitor interface pattern strings, stale struct decl
c5aa993b
JM
1133struct monitor_ops rombug_cmds =
1134{
1135 "g \r", /* execute or usually GO command */
1136 "g \r", /* continue command */
1137 "t \r", /* single step */
1138 "b %x\r", /* set a breakpoint */
1139 "k %x\r", /* clear a breakpoint */
1140 "c %x\r", /* set memory to a value */
1141 "d %x %d\r", /* display memory */
1142 "$%08X", /* prompt memory commands use */
1143 ".%s %x\r", /* set a register */
1144 ":", /* delimiter between registers */
1145 ". \r", /* read a register */
1146 "mf \r", /* download command */
1147 "RomBug: ", /* monitor command prompt */
1148 ": ", /* end-of-command delimitor */
1149 ".\r" /* optional command terminator */
c906108c
SS
1150};
1151
c5aa993b 1152struct target_ops rombug_ops;
c906108c 1153
c5aa993b
JM
1154static void
1155init_rombug_ops (void)
c906108c 1156{
c5aa993b
JM
1157 rombug_ops.to_shortname = "rombug";
1158 rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
1159 rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
c906108c 1160Specify the serial device it is connected to (e.g. /dev/ttya).",
c5aa993b
JM
1161 rombug_ops.to_open = rombug_open;
1162 rombug_ops.to_close = rombug_close;
1163 rombug_ops.to_attach = 0;
c906108c
SS
1164 rombug_ops.to_post_attach = NULL;
1165 rombug_ops.to_require_attach = NULL;
c5aa993b 1166 rombug_ops.to_detach = rombug_detach;
c906108c 1167 rombug_ops.to_require_detach = NULL;
c5aa993b
JM
1168 rombug_ops.to_resume = rombug_resume;
1169 rombug_ops.to_wait = rombug_wait;
c906108c 1170 rombug_ops.to_post_wait = NULL;
c5aa993b
JM
1171 rombug_ops.to_fetch_registers = rombug_fetch_register;
1172 rombug_ops.to_store_registers = rombug_store_register;
1173 rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
1174 rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
1175 rombug_ops.to_files_info = rombug_files_info;
1176 rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
1177 rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
1178 rombug_ops.to_terminal_init = 0;
1179 rombug_ops.to_terminal_inferior = 0;
1180 rombug_ops.to_terminal_ours_for_output = 0;
1181 rombug_ops.to_terminal_ours = 0;
1182 rombug_ops.to_terminal_info = 0; /* Terminal handling */
1183 rombug_ops.to_kill = rombug_kill;
1184 rombug_ops.to_load = rombug_load; /* load */
1185 rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
1186 rombug_ops.to_create_inferior = rombug_create_inferior;
c906108c
SS
1187 rombug_ops.to_post_startup_inferior = NULL;
1188 rombug_ops.to_acknowledge_created_inferior = NULL;
1189 rombug_ops.to_clone_and_follow_inferior = NULL;
1190 rombug_ops.to_post_follow_inferior_by_clone = NULL;
1191 rombug_ops.to_insert_fork_catchpoint = NULL;
1192 rombug_ops.to_remove_fork_catchpoint = NULL;
1193 rombug_ops.to_insert_vfork_catchpoint = NULL;
1194 rombug_ops.to_remove_vfork_catchpoint = NULL;
1195 rombug_ops.to_has_forked = NULL;
1196 rombug_ops.to_has_vforked = NULL;
1197 rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
1198 rombug_ops.to_post_follow_vfork = NULL;
1199 rombug_ops.to_insert_exec_catchpoint = NULL;
1200 rombug_ops.to_remove_exec_catchpoint = NULL;
1201 rombug_ops.to_has_execd = NULL;
1202 rombug_ops.to_reported_exec_events_per_exec_call = NULL;
1203 rombug_ops.to_has_exited = NULL;
c5aa993b
JM
1204 rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
1205 rombug_ops.to_can_run = 0; /* can_run */
1206 rombug_ops.to_notice_signals = 0; /* notice_signals */
1207 rombug_ops.to_thread_alive = 0;
1208 rombug_ops.to_stop = 0; /* to_stop */
c906108c
SS
1209 rombug_ops.to_pid_to_exec_file = NULL;
1210 rombug_ops.to_core_file_to_sym_file = NULL;
c5aa993b
JM
1211 rombug_ops.to_stratum = process_stratum;
1212 rombug_ops.DONT_USE = 0; /* next */
1213 rombug_ops.to_has_all_memory = 1;
1214 rombug_ops.to_has_memory = 1;
1215 rombug_ops.to_has_stack = 1;
1216 rombug_ops.to_has_registers = 1;
1217 rombug_ops.to_has_execution = 1; /* has execution */
1218 rombug_ops.to_sections = 0;
1219 rombug_ops.to_sections_end = 0; /* Section pointers */
1220 rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
1221}
c906108c
SS
1222
1223void
1224_initialize_remote_os9k ()
1225{
c5aa993b 1226 init_rombug_ops ();
c906108c
SS
1227 add_target (&rombug_ops);
1228
1229 add_show_from_set (
c5aa993b
JM
1230 add_set_cmd ("hash", no_class, var_boolean, (char *) &hashmark,
1231 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1232 &setlist),
1233 &showlist);
c906108c
SS
1234
1235 add_show_from_set (
c5aa993b
JM
1236 add_set_cmd ("timeout", no_class, var_zinteger,
1237 (char *) &timeout,
1238 "Set timeout in seconds for remote MIPS serial I/O.",
1239 &setlist),
1240 &showlist);
c906108c
SS
1241
1242 add_show_from_set (
c5aa993b
JM
1243 add_set_cmd ("remotelog", no_class, var_zinteger,
1244 (char *) &monitor_log,
1245 "Set monitor activity log on(=1) or off(=0).",
1246 &setlist),
1247 &showlist);
c906108c
SS
1248
1249 add_show_from_set (
c5aa993b
JM
1250 add_set_cmd ("remotexon", no_class, var_zinteger,
1251 (char *) &tty_xon,
1252 "Set remote tty line XON control",
1253 &setlist),
1254 &showlist);
c906108c
SS
1255
1256 add_show_from_set (
c5aa993b
JM
1257 add_set_cmd ("remotexoff", no_class, var_zinteger,
1258 (char *) &tty_xoff,
1259 "Set remote tty line XOFF control",
1260 &setlist),
1261 &showlist);
c906108c
SS
1262
1263 add_com ("rombug <command>", class_obscure, rombug_command,
c5aa993b 1264 "Send a command to the debug monitor.");
c906108c
SS
1265#if 0
1266 add_com ("connect", class_obscure, connect_command,
c5aa993b 1267 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
c906108c
SS
1268#endif
1269}
This page took 0.106797 seconds and 4 git commands to generate.