* monitor.c (#include "gdb_wait.h"): Removed.
[platform/upstream/binutils.git] / gdb / remote-st.c
1 /* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
2    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 /* This file was derived from remote-eb.c, which did a similar job, but for
23    an AMD-29K running EBMON.  That file was in turn derived from remote.c
24    as mentioned in the following comment (left in for comic relief):
25
26    "This is like remote.c but is for an esoteric situation--
27    having an a29k board in a PC hooked up to a unix machine with
28    a serial line, and running ctty com1 on the PC, through which
29    the unix machine can run ebmon.  Not to mention that the PC
30    has PC/NFS, so it can access the same executables that gdb can,
31    over the net in real time."
32
33    In reality, this module talks to a debug monitor called 'STDEBUG', which
34    runs in a phone switch.  We communicate with STDEBUG via either a direct
35    serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor,
36    which in turn talks to the phone switch. */
37
38 #include "defs.h"
39 #include "gdbcore.h"
40 #include "target.h"
41 #include <signal.h>
42 #include "gdb_string.h"
43 #include <sys/types.h>
44 #include "serial.h"
45
46 extern struct target_ops st2000_ops;    /* Forward declaration */
47
48 static void st2000_close ();
49 static void st2000_fetch_register ();
50 static void st2000_store_register ();
51
52 #define LOG_FILE "st2000.log"
53 #if defined (LOG_FILE)
54 FILE *log_file;
55 #endif
56
57 static int timeout = 24;
58
59 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
60    st2000_open knows that we don't have a file open when the program
61    starts.  */
62
63 static serial_t st2000_desc;
64
65 /* Send data to stdebug.  Works just like printf. */
66
67 static void
68 printf_stdebug (char *pattern,...)
69 {
70   va_list args;
71   char buf[200];
72
73   va_start (args, pattern);
74
75   vsprintf (buf, pattern, args);
76   va_end (args);
77
78   if (SERIAL_WRITE (st2000_desc, buf, strlen (buf)))
79     fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
80 }
81
82 /* Read a character from the remote system, doing all the fancy timeout
83    stuff.  */
84
85 static int
86 readchar (int timeout)
87 {
88   int c;
89
90   c = SERIAL_READCHAR (st2000_desc, timeout);
91
92 #ifdef LOG_FILE
93   putc (c & 0x7f, log_file);
94 #endif
95
96   if (c >= 0)
97     return c & 0x7f;
98
99   if (c == SERIAL_TIMEOUT)
100     {
101       if (timeout == 0)
102         return c;               /* Polls shouldn't generate timeout errors */
103
104       error ("Timeout reading from remote system.");
105     }
106
107   perror_with_name ("remote-st2000");
108 }
109
110 /* Scan input from the remote system, until STRING is found.  If DISCARD is
111    non-zero, then discard non-matching input, else print it out.
112    Let the user break out immediately.  */
113 static void
114 expect (char *string, int discard)
115 {
116   char *p = string;
117   int c;
118
119   immediate_quit++;
120   while (1)
121     {
122       c = readchar (timeout);
123       if (c == *p++)
124         {
125           if (*p == '\0')
126             {
127               immediate_quit--;
128               return;
129             }
130         }
131       else
132         {
133           if (!discard)
134             {
135               fwrite (string, 1, (p - 1) - string, stdout);
136               putchar ((char) c);
137               fflush (stdout);
138             }
139           p = string;
140         }
141     }
142 }
143
144 /* Keep discarding input until we see the STDEBUG prompt.
145
146    The convention for dealing with the prompt is that you
147    o give your command
148    o *then* wait for the prompt.
149
150    Thus the last thing that a procedure does with the serial line
151    will be an expect_prompt().  Exception:  st2000_resume does not
152    wait for the prompt, because the terminal is being handed over
153    to the inferior.  However, the next thing which happens after that
154    is a st2000_wait which does wait for the prompt.
155    Note that this includes abnormal exit, e.g. error().  This is
156    necessary to prevent getting into states from which we can't
157    recover.  */
158 static void
159 expect_prompt (int discard)
160 {
161 #if defined (LOG_FILE)
162   /* This is a convenient place to do this.  The idea is to do it often
163      enough that we never lose much data if we terminate abnormally.  */
164   fflush (log_file);
165 #endif
166   expect ("dbug> ", discard);
167 }
168
169 /* Get a hex digit from the remote system & return its value.
170    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
171 static int
172 get_hex_digit (int ignore_space)
173 {
174   int ch;
175   while (1)
176     {
177       ch = readchar (timeout);
178       if (ch >= '0' && ch <= '9')
179         return ch - '0';
180       else if (ch >= 'A' && ch <= 'F')
181         return ch - 'A' + 10;
182       else if (ch >= 'a' && ch <= 'f')
183         return ch - 'a' + 10;
184       else if (ch == ' ' && ignore_space)
185         ;
186       else
187         {
188           expect_prompt (1);
189           error ("Invalid hex digit from remote system.");
190         }
191     }
192 }
193
194 /* Get a byte from stdebug and put it in *BYT.  Accept any number
195    leading spaces.  */
196 static void
197 get_hex_byte (char *byt)
198 {
199   int val;
200
201   val = get_hex_digit (1) << 4;
202   val |= get_hex_digit (0);
203   *byt = val;
204 }
205
206 /* Get N 32-bit words from remote, each preceded by a space,
207    and put them in registers starting at REGNO.  */
208 static void
209 get_hex_regs (int n, int regno)
210 {
211   long val;
212   int i;
213
214   for (i = 0; i < n; i++)
215     {
216       int j;
217
218       val = 0;
219       for (j = 0; j < 8; j++)
220         val = (val << 4) + get_hex_digit (j == 0);
221       supply_register (regno++, (char *) &val);
222     }
223 }
224
225 /* This is called not only when we first attach, but also when the
226    user types "run" after having attached.  */
227 static void
228 st2000_create_inferior (char *execfile, char *args, char **env)
229 {
230   int entry_pt;
231
232   if (args && *args)
233     error ("Can't pass arguments to remote STDEBUG process");
234
235   if (execfile == 0 || exec_bfd == 0)
236     error ("No executable file specified");
237
238   entry_pt = (int) bfd_get_start_address (exec_bfd);
239
240 /* The "process" (board) is already stopped awaiting our commands, and
241    the program is already downloaded.  We just set its PC and go.  */
242
243   clear_proceed_status ();
244
245   /* Tell wait_for_inferior that we've started a new process.  */
246   init_wait_for_inferior ();
247
248   /* Set up the "saved terminal modes" of the inferior
249      based on what modes we are starting it with.  */
250   target_terminal_init ();
251
252   /* Install inferior's terminal modes.  */
253   target_terminal_inferior ();
254
255   /* insert_step_breakpoint ();  FIXME, do we need this?  */
256   /* Let 'er rip... */
257   proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
258 }
259
260 /* Open a connection to a remote debugger.
261    NAME is the filename used for communication.  */
262
263 static int baudrate = 9600;
264 static char dev_name[100];
265
266 static void
267 st2000_open (char *args, int from_tty)
268 {
269   int n;
270   char junk[100];
271
272   target_preopen (from_tty);
273
274   n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
275
276   if (n != 2)
277     error ("Bad arguments.  Usage: target st2000 <device> <speed>\n\
278 or target st2000 <host> <port>\n");
279
280   st2000_close (0);
281
282   st2000_desc = SERIAL_OPEN (dev_name);
283
284   if (!st2000_desc)
285     perror_with_name (dev_name);
286
287   SERIAL_SETBAUDRATE (st2000_desc, baudrate);
288
289   SERIAL_RAW (st2000_desc);
290
291   push_target (&st2000_ops);
292
293 #if defined (LOG_FILE)
294   log_file = fopen (LOG_FILE, "w");
295   if (log_file == NULL)
296     perror_with_name (LOG_FILE);
297 #endif
298
299   /* Hello?  Are you there?  */
300   printf_stdebug ("\003");      /* ^C wakes up dbug */
301
302   expect_prompt (1);
303
304   if (from_tty)
305     printf ("Remote %s connected to %s\n", target_shortname,
306             dev_name);
307 }
308
309 /* Close out all files and local state before this target loses control. */
310
311 static void
312 st2000_close (int quitting)
313 {
314   SERIAL_CLOSE (st2000_desc);
315
316 #if defined (LOG_FILE)
317   if (log_file)
318     {
319       if (ferror (log_file))
320         fprintf (stderr, "Error writing log file.\n");
321       if (fclose (log_file) != 0)
322         fprintf (stderr, "Error closing log file.\n");
323     }
324 #endif
325 }
326
327 /* Terminate the open connection to the remote debugger.
328    Use this when you want to detach and do something else
329    with your gdb.  */
330 static void
331 st2000_detach (int from_tty)
332 {
333   pop_target ();                /* calls st2000_close to do the real work */
334   if (from_tty)
335     printf ("Ending remote %s debugging\n", target_shortname);
336 }
337
338 /* Tell the remote machine to resume.  */
339
340 static void
341 st2000_resume (int pid, int step, enum target_signal sig)
342 {
343   if (step)
344     {
345       printf_stdebug ("ST\r");
346       /* Wait for the echo.  */
347       expect ("ST\r", 1);
348     }
349   else
350     {
351       printf_stdebug ("GO\r");
352       /* Swallow the echo.  */
353       expect ("GO\r", 1);
354     }
355 }
356
357 /* Wait until the remote machine stops, then return,
358    storing status in STATUS just as `wait' would.  */
359
360 static int
361 st2000_wait (struct target_waitstatus *status)
362 {
363   int old_timeout = timeout;
364
365   status->kind = TARGET_WAITKIND_EXITED;
366   status->value.integer = 0;
367
368   timeout = 0;                  /* Don't time out -- user program is running. */
369
370   expect_prompt (0);            /* Wait for prompt, outputting extraneous text */
371
372   status->kind = TARGET_WAITKIND_STOPPED;
373   status->value.sig = TARGET_SIGNAL_TRAP;
374
375   timeout = old_timeout;
376
377   return 0;
378 }
379
380 /* Return the name of register number REGNO in the form input and output by
381    STDEBUG.  Currently, REGISTER_NAMES just happens to contain exactly what
382    STDEBUG wants.  Lets take advantage of that just as long as possible! */
383
384 static char *
385 get_reg_name (int regno)
386 {
387   static char buf[50];
388   const char *p;
389   char *b;
390
391   b = buf;
392
393   for (p = REGISTER_NAME (regno); *p; p++)
394     *b++ = toupper (*p);
395   *b = '\000';
396
397   return buf;
398 }
399
400 /* Read the remote registers into the block REGS.  */
401
402 static void
403 st2000_fetch_registers (void)
404 {
405   int regno;
406
407   /* Yeah yeah, I know this is horribly inefficient.  But it isn't done
408      very often...  I'll clean it up later.  */
409
410   for (regno = 0; regno <= PC_REGNUM; regno++)
411     st2000_fetch_register (regno);
412 }
413
414 /* Fetch register REGNO, or all registers if REGNO is -1.
415    Returns errno value.  */
416 static void
417 st2000_fetch_register (int regno)
418 {
419   if (regno == -1)
420     st2000_fetch_registers ();
421   else
422     {
423       char *name = get_reg_name (regno);
424       printf_stdebug ("DR %s\r", name);
425       expect (name, 1);
426       expect (" : ", 1);
427       get_hex_regs (1, regno);
428       expect_prompt (1);
429     }
430   return;
431 }
432
433 /* Store the remote registers from the contents of the block REGS.  */
434
435 static void
436 st2000_store_registers (void)
437 {
438   int regno;
439
440   for (regno = 0; regno <= PC_REGNUM; regno++)
441     st2000_store_register (regno);
442
443   registers_changed ();
444 }
445
446 /* Store register REGNO, or all if REGNO == 0.
447    Return errno value.  */
448 static void
449 st2000_store_register (int regno)
450 {
451   if (regno == -1)
452     st2000_store_registers ();
453   else
454     {
455       printf_stdebug ("PR %s %x\r", get_reg_name (regno),
456                       read_register (regno));
457
458       expect_prompt (1);
459     }
460 }
461
462 /* Get ready to modify the registers array.  On machines which store
463    individual registers, this doesn't need to do anything.  On machines
464    which store all the registers in one fell swoop, this makes sure
465    that registers contains all the registers from the program being
466    debugged.  */
467
468 static void
469 st2000_prepare_to_store (void)
470 {
471   /* Do nothing, since we can store individual regs */
472 }
473
474 static void
475 st2000_files_info (void)
476 {
477   printf ("\tAttached to %s at %d baud.\n",
478           dev_name, baudrate);
479 }
480
481 /* Copy LEN bytes of data from debugger memory at MYADDR
482    to inferior's memory at MEMADDR.  Returns length moved.  */
483 static int
484 st2000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
485 {
486   int i;
487
488   for (i = 0; i < len; i++)
489     {
490       printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]);
491       expect_prompt (1);
492     }
493   return len;
494 }
495
496 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
497    at debugger address MYADDR.  Returns length moved.  */
498 static int
499 st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
500 {
501   int i;
502
503   /* Number of bytes read so far.  */
504   int count;
505
506   /* Starting address of this pass.  */
507   unsigned long startaddr;
508
509   /* Number of bytes to read in this pass.  */
510   int len_this_pass;
511
512   /* Note that this code works correctly if startaddr is just less
513      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
514      thing).  That is, something like
515      st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
516      works--it never adds len to memaddr and gets 0.  */
517   /* However, something like
518      st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
519      doesn't need to work.  Detect it and give up if there's an attempt
520      to do that.  */
521   if (((memaddr - 1) + len) < memaddr)
522     {
523       errno = EIO;
524       return 0;
525     }
526
527   startaddr = memaddr;
528   count = 0;
529   while (count < len)
530     {
531       len_this_pass = 16;
532       if ((startaddr % 16) != 0)
533         len_this_pass -= startaddr % 16;
534       if (len_this_pass > (len - count))
535         len_this_pass = (len - count);
536
537       printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass);
538       expect (":  ", 1);
539
540       for (i = 0; i < len_this_pass; i++)
541         get_hex_byte (&myaddr[count++]);
542
543       expect_prompt (1);
544
545       startaddr += len_this_pass;
546     }
547   return len;
548 }
549
550 /* Transfer LEN bytes between GDB address MYADDR and target address
551    MEMADDR.  If WRITE is non-zero, transfer them to the target,
552    otherwise transfer them from the target.  TARGET is unused.
553
554    Returns the number of bytes transferred. */
555
556 static int
557 st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
558                              int write, 
559                              struct mem_attrib *attrib ATTRIBUTE_UNUSED,
560                              struct target_ops *target ATTRIBUTE_UNUSED)
561 {
562   if (write)
563     return st2000_write_inferior_memory (memaddr, myaddr, len);
564   else
565     return st2000_read_inferior_memory (memaddr, myaddr, len);
566 }
567
568 static void
569 st2000_kill (char *args, int from_tty)
570 {
571   return;                       /* Ignore attempts to kill target system */
572 }
573
574 /* Clean up when a program exits.
575
576    The program actually lives on in the remote processor's RAM, and may be
577    run again without a download.  Don't leave it full of breakpoint
578    instructions.  */
579
580 static void
581 st2000_mourn_inferior (void)
582 {
583   remove_breakpoints ();
584   unpush_target (&st2000_ops);
585   generic_mourn_inferior ();    /* Do all the proper things now */
586 }
587
588 #define MAX_STDEBUG_BREAKPOINTS 16
589
590 static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] =
591 {0};
592
593 static int
594 st2000_insert_breakpoint (CORE_ADDR addr, char *shadow)
595 {
596   int i;
597   CORE_ADDR bp_addr = addr;
598   int bp_size = 0;
599
600   BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
601
602   for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++)
603     if (breakaddr[i] == 0)
604       {
605         breakaddr[i] = addr;
606
607         st2000_read_inferior_memory (bp_addr, shadow, bp_size);
608         printf_stdebug ("BR %x H\r", addr);
609         expect_prompt (1);
610         return 0;
611       }
612
613   fprintf (stderr, "Too many breakpoints (> 16) for STDBUG\n");
614   return 1;
615 }
616
617 static int
618 st2000_remove_breakpoint (CORE_ADDR addr, char *shadow)
619 {
620   int i;
621
622   for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++)
623     if (breakaddr[i] == addr)
624       {
625         breakaddr[i] = 0;
626
627         printf_stdebug ("CB %d\r", i);
628         expect_prompt (1);
629         return 0;
630       }
631
632   fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
633   return 1;
634 }
635
636
637 /* Put a command string, in args, out to STDBUG.  Output from STDBUG is placed
638    on the users terminal until the prompt is seen. */
639
640 static void
641 st2000_command (char *args, int fromtty)
642 {
643   if (!st2000_desc)
644     error ("st2000 target not open.");
645
646   if (!args)
647     error ("Missing command.");
648
649   printf_stdebug ("%s\r", args);
650   expect_prompt (0);
651 }
652
653 /* Connect the user directly to STDBUG.  This command acts just like the
654    'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
655
656 /*static struct ttystate ttystate; */
657
658 static void
659 cleanup_tty (void)
660 {
661   printf ("\r\n[Exiting connect mode]\r\n");
662 /*  SERIAL_RESTORE(0, &ttystate); */
663 }
664
665 #if 0
666 /* This all should now be in serial.c */
667
668 static void
669 connect_command (char *args, int fromtty)
670 {
671   fd_set readfds;
672   int numfds;
673   int c;
674   char cur_esc = 0;
675
676   dont_repeat ();
677
678   if (st2000_desc < 0)
679     error ("st2000 target not open.");
680
681   if (args)
682     fprintf ("This command takes no args.  They have been ignored.\n");
683
684   printf ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
685
686   serial_raw (0, &ttystate);
687
688   make_cleanup (cleanup_tty, 0);
689
690   FD_ZERO (&readfds);
691
692   while (1)
693     {
694       do
695         {
696           FD_SET (0, &readfds);
697           FD_SET (DEPRECATED_SERIAL_FD (st2000_desc), &readfds);
698           numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
699         }
700       while (numfds == 0);
701
702       if (numfds < 0)
703         perror_with_name ("select");
704
705       if (FD_ISSET (0, &readfds))
706         {                       /* tty input, send to stdebug */
707           c = getchar ();
708           if (c < 0)
709             perror_with_name ("connect");
710
711           printf_stdebug ("%c", c);
712           switch (cur_esc)
713             {
714             case 0:
715               if (c == '\r')
716                 cur_esc = c;
717               break;
718             case '\r':
719               if (c == '~')
720                 cur_esc = c;
721               else
722                 cur_esc = 0;
723               break;
724             case '~':
725               if (c == '.' || c == '\004')
726                 return;
727               else
728                 cur_esc = 0;
729             }
730         }
731
732       if (FD_ISSET (DEPRECATED_SERIAL_FD (st2000_desc), &readfds))
733         {
734           while (1)
735             {
736               c = readchar (0);
737               if (c < 0)
738                 break;
739               putchar (c);
740             }
741           fflush (stdout);
742         }
743     }
744 }
745 #endif /* 0 */
746
747 /* Define the target subroutine names */
748
749 struct target_ops st2000_ops;
750
751 static void
752 init_st2000_ops (void)
753 {
754   st2000_ops.to_shortname = "st2000";
755   st2000_ops.to_longname = "Remote serial Tandem ST2000 target";
756   st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\
757 or a network connection.\n\
758 Arguments are the name of the device for the serial line,\n\
759 the speed to connect at in bits per second.";
760   st2000_ops.to_open = st2000_open;
761   st2000_ops.to_close = st2000_close;
762   st2000_ops.to_attach = 0;
763   st2000_run_ops.to_post_attach = NULL;
764   st2000_ops.to_require_attach = NULL;
765   st2000_ops.to_detach = st2000_detach;
766   st2000_ops.to_require_detach = NULL;
767   st2000_ops.to_resume = st2000_resume;
768   st2000_ops.to_wait = st2000_wait;
769   st2000_ops.to_post_wait = NULL;
770   st2000_ops.to_fetch_registers = st2000_fetch_register;
771   st2000_ops.to_store_registers = st2000_store_register;
772   st2000_ops.to_prepare_to_store = st2000_prepare_to_store;
773   st2000_ops.to_xfer_memory = st2000_xfer_inferior_memory;
774   st2000_ops.to_files_info = st2000_files_info;
775   st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
776   st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint;   /* Breakpoints */
777   st2000_ops.to_terminal_init = 0;
778   st2000_ops.to_terminal_inferior = 0;
779   st2000_ops.to_terminal_ours_for_output = 0;
780   st2000_ops.to_terminal_ours = 0;
781   st2000_ops.to_terminal_info = 0;      /* Terminal handling */
782   st2000_ops.to_kill = st2000_kill;
783   st2000_ops.to_load = 0;       /* load */
784   st2000_ops.to_lookup_symbol = 0;      /* lookup_symbol */
785   st2000_ops.to_create_inferior = st2000_create_inferior;
786   st2000_ops.to_post_startup_inferior = NULL;
787   st2000_ops.to_acknowledge_created_inferior = NULL;
788   st2000_ops.to_clone_and_follow_inferior = NULL;
789   st2000_ops.to_post_follow_inferior_by_clone = NULL;
790   st2000_run_ops.to_insert_fork_catchpoint = NULL;
791   st2000_run_ops.to_remove_fork_catchpoint = NULL;
792   st2000_run_ops.to_insert_vfork_catchpoint = NULL;
793   st2000_run_ops.to_remove_vfork_catchpoint = NULL;
794   st2000_ops.to_has_forked = NULL;
795   st2000_ops.to_has_vforked = NULL;
796   st2000_run_ops.to_can_follow_vfork_prior_to_exec = NULL;
797   st2000_ops.to_post_follow_vfork = NULL;
798   st2000_run_ops.to_insert_exec_catchpoint = NULL;
799   st2000_run_ops.to_remove_exec_catchpoint = NULL;
800   st2000_run_ops.to_has_execd = NULL;
801   st2000_run_ops.to_reported_exec_events_per_exec_call = NULL;
802   st2000_run_ops.to_has_exited = NULL;
803   st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
804   st2000_ops.to_can_run = 0;    /* can_run */
805   st2000_ops.to_notice_signals = 0;     /* notice_signals */
806   st2000_ops.to_thread_alive = 0;       /* thread alive */
807   st2000_ops.to_stop = 0;       /* to_stop */
808   st2000_ops.to_pid_to_exec_file = NULL;
809   st2000_run_ops.to_core_file_to_sym_file = NULL;
810   st2000_ops.to_stratum = process_stratum;
811   st2000_ops.DONT_USE = 0;      /* next */
812   st2000_ops.to_has_all_memory = 1;
813   st2000_ops.to_has_memory = 1;
814   st2000_ops.to_has_stack = 1;
815   st2000_ops.to_has_registers = 1;
816   st2000_ops.to_has_execution = 1;      /* all mem, mem, stack, regs, exec */
817   st2000_ops.to_sections = 0;
818   st2000_ops.to_sections_end = 0;       /* Section pointers */
819   st2000_ops.to_magic = OPS_MAGIC;      /* Always the last thing */
820 };
821
822 void
823 _initialize_remote_st2000 (void)
824 {
825   init_st2000_ops ();
826   add_target (&st2000_ops);
827   add_com ("st2000 <command>", class_obscure, st2000_command,
828            "Send a command to the STDBUG monitor.");
829   add_com ("connect", class_obscure, connect_command,
830            "Connect the terminal directly up to the STDBUG command monitor.\n\
831 Use <CR>~. or <CR>~^D to break out.");
832 }