Protoization.
[platform/upstream/binutils.git] / gdb / remote-nindy.c
1 /* Memory-access and commands for remote NINDY process, for GDB.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
4
5    GDB is distributed in the hope that it will be useful, but WITHOUT ANY
6    WARRANTY.  No author or distributor accepts responsibility to anyone
7    for the consequences of using it or for whether it serves any
8    particular purpose or works at all, unless he says so in writing.
9    Refer to the GDB General Public License for full details.
10
11    Everyone is granted permission to copy, modify and redistribute GDB,
12    but only under the conditions described in the GDB General Public
13    License.  A copy of this license is supposed to have been given to you
14    along with GDB so you can know your rights and responsibilities.  It
15    should be in a file named COPYING.  Among other things, the copyright
16    notice and this notice must be preserved on all copies.
17
18    In other words, go ahead and share GDB, but don't try to stop
19    anyone else from sharing it farther.  Help stamp out software hoarding!
20  */
21
22 /*
23    Except for the data cache routines, this file bears little resemblence
24    to remote.c.  A new (although similar) protocol has been specified, and
25    portions of the code are entirely dependent on having an i80960 with a
26    NINDY ROM monitor at the other end of the line.
27  */
28
29 /*****************************************************************************
30  *
31  * REMOTE COMMUNICATION PROTOCOL BETWEEN GDB960 AND THE NINDY ROM MONITOR.
32  *
33  *
34  * MODES OF OPERATION
35  * ----- -- ---------
36  *      
37  * As far as NINDY is concerned, GDB is always in one of two modes: command
38  * mode or passthrough mode.
39  *
40  * In command mode (the default) pre-defined packets containing requests
41  * are sent by GDB to NINDY.  NINDY never talks except in reponse to a request.
42  *
43  * Once the the user program is started, GDB enters passthrough mode, to give
44  * the user program access to the terminal.  GDB remains in this mode until
45  * NINDY indicates that the program has stopped.
46  *
47  *
48  * PASSTHROUGH MODE
49  * ----------- ----
50  *
51  * GDB writes all input received from the keyboard directly to NINDY, and writes
52  * all characters received from NINDY directly to the monitor.
53  *
54  * Keyboard input is neither buffered nor echoed to the monitor.
55  *
56  * GDB remains in passthrough mode until NINDY sends a single ^P character,
57  * to indicate that the user process has stopped.
58  *
59  * Note:
60  *      GDB assumes NINDY performs a 'flushreg' when the user program stops.
61  *
62  *
63  * COMMAND MODE
64  * ------- ----
65  *
66  * All info (except for message ack and nak) is transferred between gdb
67  * and the remote processor in messages of the following format:
68  *
69  *              <info>#<checksum>
70  *
71  * where 
72  *      #       is a literal character
73  *
74  *      <info>  ASCII information;  all numeric information is in the
75  *              form of hex digits ('0'-'9' and lowercase 'a'-'f').
76  *
77  *      <checksum>
78  *              is a pair of ASCII hex digits representing an 8-bit
79  *              checksum formed by adding together each of the
80  *              characters in <info>.
81  *
82  * The receiver of a message always sends a single character to the sender
83  * to indicate that the checksum was good ('+') or bad ('-');  the sender
84  * re-transmits the entire message over until a '+' is received.
85  *
86  * In response to a command NINDY always sends back either data or
87  * a result code of the form "Xnn", where "nn" are hex digits and "X00"
88  * means no errors.  (Exceptions: the "s" and "c" commands don't respond.)
89  *
90  * SEE THE HEADER OF THE FILE "gdb.c" IN THE NINDY MONITOR SOURCE CODE FOR A
91  * FULL DESCRIPTION OF LEGAL COMMANDS.
92  *
93  * SEE THE FILE "stop.h" IN THE NINDY MONITOR SOURCE CODE FOR A LIST
94  * OF STOP CODES.
95  *
96  ***************************************************************************/
97
98 #include "defs.h"
99 #include <signal.h>
100 #include <sys/types.h>
101 #include <setjmp.h>
102
103 #include "frame.h"
104 #include "inferior.h"
105 #include "bfd.h"
106 #include "symfile.h"
107 #include "target.h"
108 #include "gdbcore.h"
109 #include "command.h"
110 #include "floatformat.h"
111
112 #include "gdb_wait.h"
113 #include <sys/file.h>
114 #include <ctype.h>
115 #include "serial.h"
116 #include "nindy-share/env.h"
117 #include "nindy-share/stop.h"
118
119 #include "dcache.h"
120 #include "remote-utils.h"
121
122 static DCACHE *nindy_dcache;
123
124 extern int unlink ();
125 extern char *getenv ();
126 extern char *mktemp ();
127
128 extern void generic_mourn_inferior ();
129
130 extern struct target_ops nindy_ops;
131 extern FILE *instream;
132
133 extern char ninStopWhy ();
134 extern int ninMemGet ();
135 extern int ninMemPut ();
136
137 int nindy_initial_brk;          /* nonzero if want to send an initial BREAK to nindy */
138 int nindy_old_protocol;         /* nonzero if want to use old protocol */
139 char *nindy_ttyname;            /* name of tty to talk to nindy on, or null */
140
141 #define DLE     '\020'          /* Character NINDY sends to indicate user program has
142                                    * halted.  */
143 #define TRUE    1
144 #define FALSE   0
145
146 /* From nindy-share/nindy.c.  */
147 extern serial_t nindy_serial;
148
149 static int have_regs = 0;       /* 1 iff regs read since i960 last halted */
150 static int regs_changed = 0;    /* 1 iff regs were modified since last read */
151
152 extern char *exists ();
153
154 static void nindy_fetch_registers (int);
155
156 static void nindy_store_registers (int);
157 \f
158 static char *savename;
159
160 static void
161 nindy_close (int quitting)
162 {
163   if (nindy_serial != NULL)
164     SERIAL_CLOSE (nindy_serial);
165   nindy_serial = NULL;
166
167   if (savename)
168     free (savename);
169   savename = 0;
170 }
171
172 /* Open a connection to a remote debugger.   
173    FIXME, there should be "set" commands for the options that are
174    now specified with gdb command-line options (old_protocol,
175    and initial_brk).  */
176 void
177 nindy_open (char *name,         /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */
178             int from_tty)
179 {
180   char baudrate[1024];
181
182   if (!name)
183     error_no_arg ("serial port device name");
184
185   target_preopen (from_tty);
186
187   nindy_close (0);
188
189   have_regs = regs_changed = 0;
190   nindy_dcache = dcache_init (ninMemGet, ninMemPut);
191
192   /* Allow user to interrupt the following -- we could hang if there's
193      no NINDY at the other end of the remote tty.  */
194   immediate_quit++;
195   /* If baud_rate is -1, then ninConnect will not recognize the baud rate
196      and will deal with the situation in a (more or less) reasonable
197      fashion.  */
198   sprintf (baudrate, "%d", baud_rate);
199   ninConnect (name, baudrate,
200               nindy_initial_brk, !from_tty, nindy_old_protocol);
201   immediate_quit--;
202
203   if (nindy_serial == NULL)
204     {
205       perror_with_name (name);
206     }
207
208   savename = savestring (name, strlen (name));
209   push_target (&nindy_ops);
210
211   target_fetch_registers (-1);
212
213   init_thread_list ();
214   init_wait_for_inferior ();
215   clear_proceed_status ();
216   normal_stop ();
217 }
218
219 /* User-initiated quit of nindy operations.  */
220
221 static void
222 nindy_detach (char *name, int from_tty)
223 {
224   if (name)
225     error ("Too many arguments");
226   pop_target ();
227 }
228
229 static void
230 nindy_files_info (void)
231 {
232   /* FIXME: this lies about the baud rate if we autobauded.  */
233   printf_unfiltered ("\tAttached to %s at %d bits per second%s%s.\n", savename,
234                      baud_rate,
235                      nindy_old_protocol ? " in old protocol" : "",
236                      nindy_initial_brk ? " with initial break" : "");
237 }
238 \f
239 /* Return the number of characters in the buffer before
240    the first DLE character.  */
241
242 static
243 int
244 non_dle (buf, n)
245      char *buf;                 /* Character buffer; NOT '\0'-terminated */
246      int n;                     /* Number of characters in buffer */
247 {
248   int i;
249
250   for (i = 0; i < n; i++)
251     {
252       if (buf[i] == DLE)
253         {
254           break;
255         }
256     }
257   return i;
258 }
259 \f
260 /* Tell the remote machine to resume.  */
261
262 void
263 nindy_resume (int pid, int step, enum target_signal siggnal)
264 {
265   if (siggnal != TARGET_SIGNAL_0 && siggnal != stop_signal)
266     warning ("Can't send signals to remote NINDY targets.");
267
268   dcache_flush (nindy_dcache);
269   if (regs_changed)
270     {
271       nindy_store_registers (-1);
272       regs_changed = 0;
273     }
274   have_regs = 0;
275   ninGo (step);
276 }
277 \f
278 /* FIXME, we can probably use the normal terminal_inferior stuff here.
279    We have to do terminal_inferior and then set up the passthrough
280    settings initially.  Thereafter, terminal_ours and terminal_inferior
281    will automatically swap the settings around for us.  */
282
283 struct clean_up_tty_args
284 {
285   serial_ttystate state;
286   serial_t serial;
287 };
288 static struct clean_up_tty_args tty_args;
289
290 static void
291 clean_up_tty (PTR ptrarg)
292 {
293   struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg;
294   SERIAL_SET_TTY_STATE (args->serial, args->state);
295   free (args->state);
296   warning ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
297 }
298
299 /* Recover from ^Z or ^C while remote process is running */
300 static void (*old_ctrlc) ();
301 #ifdef SIGTSTP
302 static void (*old_ctrlz) ();
303 #endif
304
305 static void
306 clean_up_int (void)
307 {
308   SERIAL_SET_TTY_STATE (tty_args.serial, tty_args.state);
309   free (tty_args.state);
310
311   signal (SIGINT, old_ctrlc);
312 #ifdef SIGTSTP
313   signal (SIGTSTP, old_ctrlz);
314 #endif
315   error ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
316 }
317
318 /* Wait until the remote machine stops. While waiting, operate in passthrough
319  * mode; i.e., pass everything NINDY sends to gdb_stdout, and everything from
320  * stdin to NINDY.
321  *
322  * Return to caller, storing status in 'status' just as `wait' would.
323  */
324
325 static int
326 nindy_wait (int pid, struct target_waitstatus *status)
327 {
328   fd_set fds;
329   int c;
330   char buf[2];
331   int i, n;
332   unsigned char stop_exit;
333   unsigned char stop_code;
334   struct cleanup *old_cleanups;
335   long ip_value, fp_value, sp_value;    /* Reg values from stop */
336
337   status->kind = TARGET_WAITKIND_EXITED;
338   status->value.integer = 0;
339
340   /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
341
342   /* Save current tty attributes, and restore them when done.  */
343   tty_args.serial = SERIAL_FDOPEN (0);
344   tty_args.state = SERIAL_GET_TTY_STATE (tty_args.serial);
345   old_ctrlc = signal (SIGINT, clean_up_int);
346 #ifdef SIGTSTP
347   old_ctrlz = signal (SIGTSTP, clean_up_int);
348 #endif
349
350   old_cleanups = make_cleanup (clean_up_tty, &tty_args);
351
352   /* Pass input from keyboard to NINDY as it arrives.  NINDY will interpret
353      <CR> and perform echo.  */
354   /* This used to set CBREAK and clear ECHO and CRMOD.  I hope this is close
355      enough.  */
356   SERIAL_RAW (tty_args.serial);
357
358   while (1)
359     {
360       /* Input on remote */
361       c = SERIAL_READCHAR (nindy_serial, -1);
362       if (c == SERIAL_ERROR)
363         {
364           error ("Cannot read from serial line");
365         }
366       else if (c == 0x1b)       /* ESC */
367         {
368           c = SERIAL_READCHAR (nindy_serial, -1);
369           c &= ~0x40;
370         }
371       else if (c != 0x10)       /* DLE */
372         /* Write out any characters preceding DLE */
373         {
374           buf[0] = (char) c;
375           write (1, buf, 1);
376         }
377       else
378         {
379           stop_exit = ninStopWhy (&stop_code,
380                                   &ip_value, &fp_value, &sp_value);
381           if (!stop_exit && (stop_code == STOP_SRQ))
382             {
383               immediate_quit++;
384               ninSrq ();
385               immediate_quit--;
386             }
387           else
388             {
389               /* Get out of loop */
390               supply_register (IP_REGNUM,
391                                (char *) &ip_value);
392               supply_register (FP_REGNUM,
393                                (char *) &fp_value);
394               supply_register (SP_REGNUM,
395                                (char *) &sp_value);
396               break;
397             }
398         }
399     }
400
401   SERIAL_SET_TTY_STATE (tty_args.serial, tty_args.state);
402   free (tty_args.state);
403   discard_cleanups (old_cleanups);
404
405   if (stop_exit)
406     {
407       status->kind = TARGET_WAITKIND_EXITED;
408       status->value.integer = stop_code;
409     }
410   else
411     {
412       /* nindy has some special stop code need to be handled */
413       if (stop_code == STOP_GDB_BPT)
414         stop_code = TRACE_STEP;
415       status->kind = TARGET_WAITKIND_STOPPED;
416       status->value.sig = i960_fault_to_signal (stop_code);
417     }
418   return inferior_pid;
419 }
420
421 /* Read the remote registers into the block REGS.  */
422
423 /* This is the block that ninRegsGet and ninRegsPut handles.  */
424 struct nindy_regs
425 {
426   char local_regs[16 * 4];
427   char global_regs[16 * 4];
428   char pcw_acw[2 * 4];
429   char ip[4];
430   char tcw[4];
431   char fp_as_double[4 * 8];
432 };
433
434 static void
435 nindy_fetch_registers (int regno)
436 {
437   struct nindy_regs nindy_regs;
438   int regnum;
439
440   immediate_quit++;
441   ninRegsGet ((char *) &nindy_regs);
442   immediate_quit--;
443
444   memcpy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16 * 4);
445   memcpy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16 * 4);
446   memcpy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2 * 4);
447   memcpy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1 * 4);
448   memcpy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1 * 4);
449   memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], nindy_regs.fp_as_double, 4 * 8);
450
451   registers_fetched ();
452 }
453
454 static void
455 nindy_prepare_to_store (void)
456 {
457   /* Fetch all regs if they aren't already here.  */
458   read_register_bytes (0, NULL, REGISTER_BYTES);
459 }
460
461 static void
462 nindy_store_registers (int regno)
463 {
464   struct nindy_regs nindy_regs;
465   int regnum;
466
467   memcpy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16 * 4);
468   memcpy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16 * 4);
469   memcpy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2 * 4);
470   memcpy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1 * 4);
471   memcpy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1 * 4);
472   memcpy (nindy_regs.fp_as_double, &registers[REGISTER_BYTE (FP0_REGNUM)], 8 * 4);
473
474   immediate_quit++;
475   ninRegsPut ((char *) &nindy_regs);
476   immediate_quit--;
477 }
478
479 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
480    to debugger memory starting at MYADDR.   Copy to inferior if
481    SHOULD_WRITE is nonzero.  Returns the length copied. */
482
483 int
484 nindy_xfer_inferior_memory (memaddr, myaddr, len, should_write, target)
485      CORE_ADDR memaddr;
486      char *myaddr;
487      int len;
488      int should_write;
489      struct target_ops *target; /* ignored */
490 {
491   if (len <= 0)
492     return 0;
493   return dcache_xfer_memory (nindy_dcache, memaddr, myaddr, 
494                              len, should_write);
495 }
496 \f
497 static void
498 nindy_create_inferior (char *execfile, char *args, char **env)
499 {
500   int entry_pt;
501   int pid;
502
503   if (args && *args)
504     error ("Can't pass arguments to remote NINDY process");
505
506   if (execfile == 0 || exec_bfd == 0)
507     error ("No executable file specified");
508
509   entry_pt = (int) bfd_get_start_address (exec_bfd);
510
511   pid = 42;
512
513   /* The "process" (board) is already stopped awaiting our commands, and
514      the program is already downloaded.  We just set its PC and go.  */
515
516   inferior_pid = pid;           /* Needed for wait_for_inferior below */
517
518   clear_proceed_status ();
519
520   /* Tell wait_for_inferior that we've started a new process.  */
521   init_wait_for_inferior ();
522
523   /* Set up the "saved terminal modes" of the inferior
524      based on what modes we are starting it with.  */
525   target_terminal_init ();
526
527   /* Install inferior's terminal modes.  */
528   target_terminal_inferior ();
529
530   /* insert_step_breakpoint ();  FIXME, do we need this?  */
531   /* Let 'er rip... */
532   proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
533 }
534
535 static void
536 reset_command (char *args, int from_tty)
537 {
538   if (nindy_serial == NULL)
539     {
540       error ("No target system to reset -- use 'target nindy' command.");
541     }
542   if (query ("Really reset the target system?", 0, 0))
543     {
544       SERIAL_SEND_BREAK (nindy_serial);
545       tty_flush (nindy_serial);
546     }
547 }
548
549 void
550 nindy_kill (char *args, int from_tty)
551 {
552   return;                       /* Ignore attempts to kill target system */
553 }
554
555 /* Clean up when a program exits.
556
557    The program actually lives on in the remote processor's RAM, and may be
558    run again without a download.  Don't leave it full of breakpoint
559    instructions.  */
560
561 void
562 nindy_mourn_inferior (void)
563 {
564   remove_breakpoints ();
565   unpush_target (&nindy_ops);
566   generic_mourn_inferior ();    /* Do all the proper things now */
567 }
568 \f
569 /* Pass the args the way catch_errors wants them.  */
570 static int
571 nindy_open_stub (char *arg)
572 {
573   nindy_open (arg, 1);
574   return 1;
575 }
576
577 static void
578 nindy_load (char *filename, int from_tty)
579 {
580   asection *s;
581   /* Can't do unix style forking on a VMS system, so we'll use bfd to do
582      all the work for us
583    */
584
585   bfd *file = bfd_openr (filename, 0);
586   if (!file)
587     {
588       perror_with_name (filename);
589       return;
590     }
591
592   if (!bfd_check_format (file, bfd_object))
593     {
594       error ("can't prove it's an object file\n");
595       return;
596     }
597
598   for (s = file->sections; s; s = s->next)
599     {
600       if (s->flags & SEC_LOAD)
601         {
602           char *buffer = xmalloc (s->_raw_size);
603           bfd_get_section_contents (file, s, buffer, 0, s->_raw_size);
604           printf ("Loading section %s, size %x vma %x\n",
605                   s->name,
606                   s->_raw_size,
607                   s->vma);
608           ninMemPut (s->vma, buffer, s->_raw_size);
609           free (buffer);
610         }
611     }
612   bfd_close (file);
613 }
614
615 static int
616 load_stub (char *arg)
617 {
618   target_load (arg, 1);
619   return 1;
620 }
621
622 /* This routine is run as a hook, just before the main command loop is
623    entered.  If gdb is configured for the i960, but has not had its
624    nindy target specified yet, this will loop prompting the user to do so.
625
626    Unlike the loop provided by Intel, we actually let the user get out
627    of this with a RETURN.  This is useful when e.g. simply examining
628    an i960 object file on the host system.  */
629
630 void
631 nindy_before_main_loop (void)
632 {
633   char ttyname[100];
634   char *p, *p2;
635
636   while (target_stack->target_ops != &nindy_ops)        /* What is this crap??? */
637     {                           /* remote tty not specified yet */
638       if (instream == stdin)
639         {
640           printf_unfiltered ("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit:  ");
641           gdb_flush (gdb_stdout);
642         }
643       fgets (ttyname, sizeof (ttyname) - 1, stdin);
644
645       /* Strip leading and trailing whitespace */
646       for (p = ttyname; isspace (*p); p++)
647         {
648           ;
649         }
650       if (*p == '\0')
651         {
652           return;               /* User just hit spaces or return, wants out */
653         }
654       for (p2 = p; !isspace (*p2) && (*p2 != '\0'); p2++)
655         {
656           ;
657         }
658       *p2 = '\0';
659       if (STREQ ("quit", p))
660         {
661           exit (1);
662         }
663
664       if (catch_errors (nindy_open_stub, p, "", RETURN_MASK_ALL))
665         {
666           /* Now that we have a tty open for talking to the remote machine,
667              download the executable file if one was specified.  */
668           if (exec_bfd)
669             {
670               catch_errors (load_stub, bfd_get_filename (exec_bfd), "",
671                             RETURN_MASK_ALL);
672             }
673         }
674     }
675 }
676 \f
677 /* Define the target subroutine names */
678
679 struct target_ops nindy_ops;
680
681 static void
682 init_nindy_ops (void)
683 {
684   nindy_ops.to_shortname = "nindy";
685   "Remote serial target in i960 NINDY-specific protocol",
686     nindy_ops.to_longname = "Use a remote i960 system running NINDY connected by a serial line.\n\
687 Specify the name of the device the serial line is connected to.\n\
688 The speed (baud rate), whether to use the old NINDY protocol,\n\
689 and whether to send a break on startup, are controlled by options\n\
690 specified when you started GDB.";
691   nindy_ops.to_doc = "";
692   nindy_ops.to_open = nindy_open;
693   nindy_ops.to_close = nindy_close;
694   nindy_ops.to_attach = 0;
695   nindy_ops.to_post_attach = NULL;
696   nindy_ops.to_require_attach = NULL;
697   nindy_ops.to_detach = nindy_detach;
698   nindy_ops.to_require_detach = NULL;
699   nindy_ops.to_resume = nindy_resume;
700   nindy_ops.to_wait = nindy_wait;
701   nindy_ops.to_post_wait = NULL;
702   nindy_ops.to_fetch_registers = nindy_fetch_registers;
703   nindy_ops.to_store_registers = nindy_store_registers;
704   nindy_ops.to_prepare_to_store = nindy_prepare_to_store;
705   nindy_ops.to_xfer_memory = nindy_xfer_inferior_memory;
706   nindy_ops.to_files_info = nindy_files_info;
707   nindy_ops.to_insert_breakpoint = memory_insert_breakpoint;
708   nindy_ops.to_remove_breakpoint = memory_remove_breakpoint;
709   nindy_ops.to_terminal_init = 0;
710   nindy_ops.to_terminal_inferior = 0;
711   nindy_ops.to_terminal_ours_for_output = 0;
712   nindy_ops.to_terminal_ours = 0;
713   nindy_ops.to_terminal_info = 0;       /* Terminal crud */
714   nindy_ops.to_kill = nindy_kill;
715   nindy_ops.to_load = nindy_load;
716   nindy_ops.to_lookup_symbol = 0;       /* lookup_symbol */
717   nindy_ops.to_create_inferior = nindy_create_inferior;
718   nindy_ops.to_post_startup_inferior = NULL;
719   nindy_ops.to_acknowledge_created_inferior = NULL;
720   nindy_ops.to_clone_and_follow_inferior = NULL;
721   nindy_ops.to_post_follow_inferior_by_clone = NULL;
722   nindy_ops.to_insert_fork_catchpoint = NULL;
723   nindy_ops.to_remove_fork_catchpoint = NULL;
724   nindy_ops.to_insert_vfork_catchpoint = NULL;
725   nindy_ops.to_remove_vfork_catchpoint = NULL;
726   nindy_ops.to_has_forked = NULL;
727   nindy_ops.to_has_vforked = NULL;
728   nindy_ops.to_can_follow_vfork_prior_to_exec = NULL;
729   nindy_ops.to_post_follow_vfork = NULL;
730   nindy_ops.to_insert_exec_catchpoint = NULL;
731   nindy_ops.to_remove_exec_catchpoint = NULL;
732   nindy_ops.to_has_execd = NULL;
733   nindy_ops.to_reported_exec_events_per_exec_call = NULL;
734   nindy_ops.to_has_exited = NULL;
735   nindy_ops.to_mourn_inferior = nindy_mourn_inferior;
736   nindy_ops.to_can_run = 0;     /* can_run */
737   nindy_ops.to_notice_signals = 0;      /* notice_signals */
738   nindy_ops.to_thread_alive = 0;        /* to_thread_alive */
739   nindy_ops.to_stop = 0;        /* to_stop */
740   nindy_ops.to_pid_to_exec_file = NULL;
741   nindy_ops.to_core_file_to_sym_file = NULL;
742   nindy_ops.to_stratum = process_stratum;
743   nindy_ops.DONT_USE = 0;       /* next */
744   nindy_ops.to_has_all_memory = 1;
745   nindy_ops.to_has_memory = 1;
746   nindy_ops.to_has_stack = 1;
747   nindy_ops.to_has_registers = 1;
748   nindy_ops.to_has_execution = 1;       /* all mem, mem, stack, regs, exec */
749   nindy_ops.to_sections = 0;
750   nindy_ops.to_sections_end = 0;        /* Section pointers */
751   nindy_ops.to_magic = OPS_MAGIC;       /* Always the last thing */
752 }
753
754 void
755 _initialize_nindy (void)
756 {
757   init_nindy_ops ();
758   add_target (&nindy_ops);
759   add_com ("reset", class_obscure, reset_command,
760            "Send a 'break' to the remote target system.\n\
761 Only useful if the target has been equipped with a circuit\n\
762 to perform a hard reset when a break is detected.");
763 }