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