import gdb-1999-07-07 post reformat
[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 "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
155 nindy_fetch_registers PARAMS ((int));
156
157 static void
158 nindy_store_registers PARAMS ((int));
159 \f
160 static char *savename;
161
162 static void
163 nindy_close (quitting)
164      int quitting;
165 {
166   if (nindy_serial != NULL)
167     SERIAL_CLOSE (nindy_serial);
168   nindy_serial = NULL;
169
170   if (savename)
171     free (savename);
172   savename = 0;
173 }
174
175 /* Open a connection to a remote debugger.   
176    FIXME, there should be "set" commands for the options that are
177    now specified with gdb command-line options (old_protocol,
178    and initial_brk).  */
179 void
180 nindy_open (name, from_tty)
181      char *name;                /* "/dev/ttyXX", "ttyXX", or "XX": tty to be opened */
182      int from_tty;
183 {
184   char baudrate[1024];
185
186   if (!name)
187     error_no_arg ("serial port device name");
188
189   target_preopen (from_tty);
190
191   nindy_close (0);
192
193   have_regs = regs_changed = 0;
194   nindy_dcache = dcache_init (ninMemGet, ninMemPut);
195
196   /* Allow user to interrupt the following -- we could hang if there's
197      no NINDY at the other end of the remote tty.  */
198   immediate_quit++;
199   /* If baud_rate is -1, then ninConnect will not recognize the baud rate
200      and will deal with the situation in a (more or less) reasonable
201      fashion.  */
202   sprintf (baudrate, "%d", baud_rate);
203   ninConnect (name, baudrate,
204               nindy_initial_brk, !from_tty, nindy_old_protocol);
205   immediate_quit--;
206
207   if (nindy_serial == NULL)
208     {
209       perror_with_name (name);
210     }
211
212   savename = savestring (name, strlen (name));
213   push_target (&nindy_ops);
214
215   target_fetch_registers (-1);
216
217   init_thread_list ();
218   init_wait_for_inferior ();
219   clear_proceed_status ();
220   normal_stop ();
221 }
222
223 /* User-initiated quit of nindy operations.  */
224
225 static void
226 nindy_detach (name, from_tty)
227      char *name;
228      int from_tty;
229 {
230   if (name)
231     error ("Too many arguments");
232   pop_target ();
233 }
234
235 static void
236 nindy_files_info ()
237 {
238   /* FIXME: this lies about the baud rate if we autobauded.  */
239   printf_unfiltered ("\tAttached to %s at %d bits per second%s%s.\n", savename,
240                      baud_rate,
241                      nindy_old_protocol ? " in old protocol" : "",
242                      nindy_initial_brk ? " with initial break" : "");
243 }
244 \f
245 /* Return the number of characters in the buffer before
246    the first DLE character.  */
247
248 static
249 int
250 non_dle (buf, n)
251      char *buf;                 /* Character buffer; NOT '\0'-terminated */
252      int n;                     /* Number of characters in buffer */
253 {
254   int i;
255
256   for (i = 0; i < n; i++)
257     {
258       if (buf[i] == DLE)
259         {
260           break;
261         }
262     }
263   return i;
264 }
265 \f
266 /* Tell the remote machine to resume.  */
267
268 void
269 nindy_resume (pid, step, siggnal)
270      int pid, step;
271      enum target_signal siggnal;
272 {
273   if (siggnal != TARGET_SIGNAL_0 && siggnal != stop_signal)
274     warning ("Can't send signals to remote NINDY targets.");
275
276   dcache_flush (nindy_dcache);
277   if (regs_changed)
278     {
279       nindy_store_registers (-1);
280       regs_changed = 0;
281     }
282   have_regs = 0;
283   ninGo (step);
284 }
285 \f
286 /* FIXME, we can probably use the normal terminal_inferior stuff here.
287    We have to do terminal_inferior and then set up the passthrough
288    settings initially.  Thereafter, terminal_ours and terminal_inferior
289    will automatically swap the settings around for us.  */
290
291 struct clean_up_tty_args
292 {
293   serial_ttystate state;
294   serial_t serial;
295 };
296 static struct clean_up_tty_args tty_args;
297
298 static void
299 clean_up_tty (ptrarg)
300      PTR ptrarg;
301 {
302   struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg;
303   SERIAL_SET_TTY_STATE (args->serial, args->state);
304   free (args->state);
305   warning ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
306 }
307
308 /* Recover from ^Z or ^C while remote process is running */
309 static void (*old_ctrlc) ();
310 #ifdef SIGTSTP
311 static void (*old_ctrlz) ();
312 #endif
313
314 static void
315 clean_up_int ()
316 {
317   SERIAL_SET_TTY_STATE (tty_args.serial, tty_args.state);
318   free (tty_args.state);
319
320   signal (SIGINT, old_ctrlc);
321 #ifdef SIGTSTP
322   signal (SIGTSTP, old_ctrlz);
323 #endif
324   error ("\n\nYou may need to reset the 80960 and/or reload your program.\n");
325 }
326
327 /* Wait until the remote machine stops. While waiting, operate in passthrough
328  * mode; i.e., pass everything NINDY sends to gdb_stdout, and everything from
329  * stdin to NINDY.
330  *
331  * Return to caller, storing status in 'status' just as `wait' would.
332  */
333
334 static int
335 nindy_wait (pid, status)
336      int pid;
337      struct target_waitstatus *status;
338 {
339   fd_set fds;
340   int c;
341   char buf[2];
342   int i, n;
343   unsigned char stop_exit;
344   unsigned char stop_code;
345   struct cleanup *old_cleanups;
346   long ip_value, fp_value, sp_value;    /* Reg values from stop */
347
348   status->kind = TARGET_WAITKIND_EXITED;
349   status->value.integer = 0;
350
351   /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
352
353   /* Save current tty attributes, and restore them when done.  */
354   tty_args.serial = SERIAL_FDOPEN (0);
355   tty_args.state = SERIAL_GET_TTY_STATE (tty_args.serial);
356   old_ctrlc = signal (SIGINT, clean_up_int);
357 #ifdef SIGTSTP
358   old_ctrlz = signal (SIGTSTP, clean_up_int);
359 #endif
360
361   old_cleanups = make_cleanup (clean_up_tty, &tty_args);
362
363   /* Pass input from keyboard to NINDY as it arrives.  NINDY will interpret
364      <CR> and perform echo.  */
365   /* This used to set CBREAK and clear ECHO and CRMOD.  I hope this is close
366      enough.  */
367   SERIAL_RAW (tty_args.serial);
368
369   while (1)
370     {
371       /* Input on remote */
372       c = SERIAL_READCHAR (nindy_serial, -1);
373       if (c == SERIAL_ERROR)
374         {
375           error ("Cannot read from serial line");
376         }
377       else if (c == 0x1b)       /* ESC */
378         {
379           c = SERIAL_READCHAR (nindy_serial, -1);
380           c &= ~0x40;
381         }
382       else if (c != 0x10)       /* DLE */
383         /* Write out any characters preceding DLE */
384         {
385           buf[0] = (char) c;
386           write (1, buf, 1);
387         }
388       else
389         {
390           stop_exit = ninStopWhy (&stop_code,
391                                   &ip_value, &fp_value, &sp_value);
392           if (!stop_exit && (stop_code == STOP_SRQ))
393             {
394               immediate_quit++;
395               ninSrq ();
396               immediate_quit--;
397             }
398           else
399             {
400               /* Get out of loop */
401               supply_register (IP_REGNUM,
402                                (char *) &ip_value);
403               supply_register (FP_REGNUM,
404                                (char *) &fp_value);
405               supply_register (SP_REGNUM,
406                                (char *) &sp_value);
407               break;
408             }
409         }
410     }
411
412   SERIAL_SET_TTY_STATE (tty_args.serial, tty_args.state);
413   free (tty_args.state);
414   discard_cleanups (old_cleanups);
415
416   if (stop_exit)
417     {
418       status->kind = TARGET_WAITKIND_EXITED;
419       status->value.integer = stop_code;
420     }
421   else
422     {
423       /* nindy has some special stop code need to be handled */
424       if (stop_code == STOP_GDB_BPT)
425         stop_code = TRACE_STEP;
426       status->kind = TARGET_WAITKIND_STOPPED;
427       status->value.sig = i960_fault_to_signal (stop_code);
428     }
429   return inferior_pid;
430 }
431
432 /* Read the remote registers into the block REGS.  */
433
434 /* This is the block that ninRegsGet and ninRegsPut handles.  */
435 struct nindy_regs
436 {
437   char local_regs[16 * 4];
438   char global_regs[16 * 4];
439   char pcw_acw[2 * 4];
440   char ip[4];
441   char tcw[4];
442   char fp_as_double[4 * 8];
443 };
444
445 static void
446 nindy_fetch_registers (regno)
447      int regno;
448 {
449   struct nindy_regs nindy_regs;
450   int regnum;
451
452   immediate_quit++;
453   ninRegsGet ((char *) &nindy_regs);
454   immediate_quit--;
455
456   memcpy (&registers[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16 * 4);
457   memcpy (&registers[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16 * 4);
458   memcpy (&registers[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2 * 4);
459   memcpy (&registers[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1 * 4);
460   memcpy (&registers[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1 * 4);
461   memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], nindy_regs.fp_as_double, 4 * 8);
462
463   registers_fetched ();
464 }
465
466 static void
467 nindy_prepare_to_store ()
468 {
469   /* Fetch all regs if they aren't already here.  */
470   read_register_bytes (0, NULL, REGISTER_BYTES);
471 }
472
473 static void
474 nindy_store_registers (regno)
475      int regno;
476 {
477   struct nindy_regs nindy_regs;
478   int regnum;
479
480   memcpy (nindy_regs.local_regs, &registers[REGISTER_BYTE (R0_REGNUM)], 16 * 4);
481   memcpy (nindy_regs.global_regs, &registers[REGISTER_BYTE (G0_REGNUM)], 16 * 4);
482   memcpy (nindy_regs.pcw_acw, &registers[REGISTER_BYTE (PCW_REGNUM)], 2 * 4);
483   memcpy (nindy_regs.ip, &registers[REGISTER_BYTE (IP_REGNUM)], 1 * 4);
484   memcpy (nindy_regs.tcw, &registers[REGISTER_BYTE (TCW_REGNUM)], 1 * 4);
485   memcpy (nindy_regs.fp_as_double, &registers[REGISTER_BYTE (FP0_REGNUM)], 8 * 4);
486
487   immediate_quit++;
488   ninRegsPut ((char *) &nindy_regs);
489   immediate_quit--;
490 }
491
492 /* Read a word from remote address ADDR and return it.
493  * This goes through the data cache.
494  */
495 int
496 nindy_fetch_word (addr)
497      CORE_ADDR addr;
498 {
499   return dcache_fetch (nindy_dcache, addr);
500 }
501
502 /* Write a word WORD into remote address ADDR.
503    This goes through the data cache.  */
504
505 void
506 nindy_store_word (addr, word)
507      CORE_ADDR addr;
508      int word;
509 {
510   dcache_poke (nindy_dcache, addr, word);
511 }
512
513 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
514    to debugger memory starting at MYADDR.   Copy to inferior if
515    WRITE is nonzero.  Returns the length copied.
516
517    This is stolen almost directly from infptrace.c's child_xfer_memory,
518    which also deals with a word-oriented memory interface.  Sometime,
519    FIXME, rewrite this to not use the word-oriented routines.  */
520
521 int
522 nindy_xfer_inferior_memory (memaddr, myaddr, len, should_write, target)
523      CORE_ADDR memaddr;
524      char *myaddr;
525      int len;
526      int should_write;
527      struct target_ops *target; /* ignored */
528 {
529   register int i;
530   /* Round starting address down to longword boundary.  */
531   register CORE_ADDR addr = memaddr & -sizeof (int);
532   /* Round ending address up; get number of longwords that makes.  */
533   register int count
534   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
535   /* Allocate buffer of that many longwords.  */
536   register int *buffer = (int *) alloca (count * sizeof (int));
537
538   if (should_write)
539     {
540       /* Fill start and end extra bytes of buffer with existing memory data.  */
541
542       if (addr != memaddr || len < (int) sizeof (int))
543         {
544           /* Need part of initial word -- fetch it.  */
545           buffer[0] = nindy_fetch_word (addr);
546         }
547
548       if (count > 1)            /* FIXME, avoid if even boundary */
549         {
550           buffer[count - 1]
551             = nindy_fetch_word (addr + (count - 1) * sizeof (int));
552         }
553
554       /* Copy data to be written over corresponding part of buffer */
555
556       memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
557
558       /* Write the entire buffer.  */
559
560       for (i = 0; i < count; i++, addr += sizeof (int))
561         {
562           errno = 0;
563           nindy_store_word (addr, buffer[i]);
564           if (errno)
565             return 0;
566         }
567     }
568   else
569     {
570       /* Read all the longwords */
571       for (i = 0; i < count; i++, addr += sizeof (int))
572         {
573           errno = 0;
574           buffer[i] = nindy_fetch_word (addr);
575           if (errno)
576             return 0;
577           QUIT;
578         }
579
580       /* Copy appropriate bytes out of the buffer.  */
581       memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
582     }
583   return len;
584 }
585 \f
586 static void
587 nindy_create_inferior (execfile, args, env)
588      char *execfile;
589      char *args;
590      char **env;
591 {
592   int entry_pt;
593   int pid;
594
595   if (args && *args)
596     error ("Can't pass arguments to remote NINDY process");
597
598   if (execfile == 0 || exec_bfd == 0)
599     error ("No executable file specified");
600
601   entry_pt = (int) bfd_get_start_address (exec_bfd);
602
603   pid = 42;
604
605   /* The "process" (board) is already stopped awaiting our commands, and
606      the program is already downloaded.  We just set its PC and go.  */
607
608   inferior_pid = pid;           /* Needed for wait_for_inferior below */
609
610   clear_proceed_status ();
611
612   /* Tell wait_for_inferior that we've started a new process.  */
613   init_wait_for_inferior ();
614
615   /* Set up the "saved terminal modes" of the inferior
616      based on what modes we are starting it with.  */
617   target_terminal_init ();
618
619   /* Install inferior's terminal modes.  */
620   target_terminal_inferior ();
621
622   /* insert_step_breakpoint ();  FIXME, do we need this?  */
623   /* Let 'er rip... */
624   proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
625 }
626
627 static void
628 reset_command (args, from_tty)
629      char *args;
630      int from_tty;
631 {
632   if (nindy_serial == NULL)
633     {
634       error ("No target system to reset -- use 'target nindy' command.");
635     }
636   if (query ("Really reset the target system?", 0, 0))
637     {
638       SERIAL_SEND_BREAK (nindy_serial);
639       tty_flush (nindy_serial);
640     }
641 }
642
643 void
644 nindy_kill (args, from_tty)
645      char *args;
646      int from_tty;
647 {
648   return;                       /* Ignore attempts to kill target system */
649 }
650
651 /* Clean up when a program exits.
652
653    The program actually lives on in the remote processor's RAM, and may be
654    run again without a download.  Don't leave it full of breakpoint
655    instructions.  */
656
657 void
658 nindy_mourn_inferior ()
659 {
660   remove_breakpoints ();
661   unpush_target (&nindy_ops);
662   generic_mourn_inferior ();    /* Do all the proper things now */
663 }
664 \f
665 /* Pass the args the way catch_errors wants them.  */
666 static int
667 nindy_open_stub (arg)
668      char *arg;
669 {
670   nindy_open (arg, 1);
671   return 1;
672 }
673
674 static void
675 nindy_load (filename, from_tty)
676      char *filename;
677      int from_tty;
678 {
679   asection *s;
680   /* Can't do unix style forking on a VMS system, so we'll use bfd to do
681      all the work for us
682    */
683
684   bfd *file = bfd_openr (filename, 0);
685   if (!file)
686     {
687       perror_with_name (filename);
688       return;
689     }
690
691   if (!bfd_check_format (file, bfd_object))
692     {
693       error ("can't prove it's an object file\n");
694       return;
695     }
696
697   for (s = file->sections; s; s = s->next)
698     {
699       if (s->flags & SEC_LOAD)
700         {
701           char *buffer = xmalloc (s->_raw_size);
702           bfd_get_section_contents (file, s, buffer, 0, s->_raw_size);
703           printf ("Loading section %s, size %x vma %x\n",
704                   s->name,
705                   s->_raw_size,
706                   s->vma);
707           ninMemPut (s->vma, buffer, s->_raw_size);
708           free (buffer);
709         }
710     }
711   bfd_close (file);
712 }
713
714 static int
715 load_stub (arg)
716      char *arg;
717 {
718   target_load (arg, 1);
719   return 1;
720 }
721
722 /* This routine is run as a hook, just before the main command loop is
723    entered.  If gdb is configured for the i960, but has not had its
724    nindy target specified yet, this will loop prompting the user to do so.
725
726    Unlike the loop provided by Intel, we actually let the user get out
727    of this with a RETURN.  This is useful when e.g. simply examining
728    an i960 object file on the host system.  */
729
730 void
731 nindy_before_main_loop ()
732 {
733   char ttyname[100];
734   char *p, *p2;
735
736   while (target_stack->target_ops != &nindy_ops)        /* What is this crap??? */
737     {                           /* remote tty not specified yet */
738       if (instream == stdin)
739         {
740           printf_unfiltered ("\nAttach /dev/ttyNN -- specify NN, or \"quit\" to quit:  ");
741           gdb_flush (gdb_stdout);
742         }
743       fgets (ttyname, sizeof (ttyname) - 1, stdin);
744
745       /* Strip leading and trailing whitespace */
746       for (p = ttyname; isspace (*p); p++)
747         {
748           ;
749         }
750       if (*p == '\0')
751         {
752           return;               /* User just hit spaces or return, wants out */
753         }
754       for (p2 = p; !isspace (*p2) && (*p2 != '\0'); p2++)
755         {
756           ;
757         }
758       *p2 = '\0';
759       if (STREQ ("quit", p))
760         {
761           exit (1);
762         }
763
764       if (catch_errors (nindy_open_stub, p, "", RETURN_MASK_ALL))
765         {
766           /* Now that we have a tty open for talking to the remote machine,
767              download the executable file if one was specified.  */
768           if (exec_bfd)
769             {
770               catch_errors (load_stub, bfd_get_filename (exec_bfd), "",
771                             RETURN_MASK_ALL);
772             }
773         }
774     }
775 }
776 \f
777 /* Define the target subroutine names */
778
779 struct target_ops nindy_ops;
780
781 static void
782 init_nindy_ops (void)
783 {
784   nindy_ops.to_shortname = "nindy";
785   "Remote serial target in i960 NINDY-specific protocol",
786     nindy_ops.to_longname = "Use a remote i960 system running NINDY connected by a serial line.\n\
787 Specify the name of the device the serial line is connected to.\n\
788 The speed (baud rate), whether to use the old NINDY protocol,\n\
789 and whether to send a break on startup, are controlled by options\n\
790 specified when you started GDB.";
791   nindy_ops.to_doc = "";
792   nindy_ops.to_open = nindy_open;
793   nindy_ops.to_close = nindy_close;
794   nindy_ops.to_attach = 0;
795   nindy_ops.to_post_attach = NULL;
796   nindy_ops.to_require_attach = NULL;
797   nindy_ops.to_detach = nindy_detach;
798   nindy_ops.to_require_detach = NULL;
799   nindy_ops.to_resume = nindy_resume;
800   nindy_ops.to_wait = nindy_wait;
801   nindy_ops.to_post_wait = NULL;
802   nindy_ops.to_fetch_registers = nindy_fetch_registers;
803   nindy_ops.to_store_registers = nindy_store_registers;
804   nindy_ops.to_prepare_to_store = nindy_prepare_to_store;
805   nindy_ops.to_xfer_memory = nindy_xfer_inferior_memory;
806   nindy_ops.to_files_info = nindy_files_info;
807   nindy_ops.to_insert_breakpoint = memory_insert_breakpoint;
808   nindy_ops.to_remove_breakpoint = memory_remove_breakpoint;
809   nindy_ops.to_terminal_init = 0;
810   nindy_ops.to_terminal_inferior = 0;
811   nindy_ops.to_terminal_ours_for_output = 0;
812   nindy_ops.to_terminal_ours = 0;
813   nindy_ops.to_terminal_info = 0;       /* Terminal crud */
814   nindy_ops.to_kill = nindy_kill;
815   nindy_ops.to_load = nindy_load;
816   nindy_ops.to_lookup_symbol = 0;       /* lookup_symbol */
817   nindy_ops.to_create_inferior = nindy_create_inferior;
818   nindy_ops.to_post_startup_inferior = NULL;
819   nindy_ops.to_acknowledge_created_inferior = NULL;
820   nindy_ops.to_clone_and_follow_inferior = NULL;
821   nindy_ops.to_post_follow_inferior_by_clone = NULL;
822   nindy_ops.to_insert_fork_catchpoint = NULL;
823   nindy_ops.to_remove_fork_catchpoint = NULL;
824   nindy_ops.to_insert_vfork_catchpoint = NULL;
825   nindy_ops.to_remove_vfork_catchpoint = NULL;
826   nindy_ops.to_has_forked = NULL;
827   nindy_ops.to_has_vforked = NULL;
828   nindy_ops.to_can_follow_vfork_prior_to_exec = NULL;
829   nindy_ops.to_post_follow_vfork = NULL;
830   nindy_ops.to_insert_exec_catchpoint = NULL;
831   nindy_ops.to_remove_exec_catchpoint = NULL;
832   nindy_ops.to_has_execd = NULL;
833   nindy_ops.to_reported_exec_events_per_exec_call = NULL;
834   nindy_ops.to_has_exited = NULL;
835   nindy_ops.to_mourn_inferior = nindy_mourn_inferior;
836   nindy_ops.to_can_run = 0;     /* can_run */
837   nindy_ops.to_notice_signals = 0;      /* notice_signals */
838   nindy_ops.to_thread_alive = 0;        /* to_thread_alive */
839   nindy_ops.to_stop = 0;        /* to_stop */
840   nindy_ops.to_pid_to_exec_file = NULL;
841   nindy_ops.to_core_file_to_sym_file = NULL;
842   nindy_ops.to_stratum = process_stratum;
843   nindy_ops.DONT_USE = 0;       /* next */
844   nindy_ops.to_has_all_memory = 1;
845   nindy_ops.to_has_memory = 1;
846   nindy_ops.to_has_stack = 1;
847   nindy_ops.to_has_registers = 1;
848   nindy_ops.to_has_execution = 1;       /* all mem, mem, stack, regs, exec */
849   nindy_ops.to_sections = 0;
850   nindy_ops.to_sections_end = 0;        /* Section pointers */
851   nindy_ops.to_magic = OPS_MAGIC;       /* Always the last thing */
852 }
853
854 void
855 _initialize_nindy ()
856 {
857   init_nindy_ops ();
858   add_target (&nindy_ops);
859   add_com ("reset", class_obscure, reset_command,
860            "Send a 'break' to the remote target system.\n\
861 Only useful if the target has been equipped with a circuit\n\
862 to perform a hard reset when a break is detected.");
863 }