OSDN Git Service

From Paul Hilfinger. Add attribs param to hpux_thread_xfer_memory.
[pf3gnuchains/pf3gnuchains3x.git] / gdb / remote-adapt.c
1 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. 
2    Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
3    Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
4    Adapted from work done at Cygnus Support in remote-eb.c.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 /* This is like remote.c but is for an esoteric situation--
24    having a 29k board attached to an Adapt inline monitor. 
25    The  monitor is connected via serial line to a unix machine 
26    running gdb. 
27
28    3/91 -  developed on Sun3 OS 4.1, by David Wood
29    o - I can't get binary coff to load. 
30    o - I can't get 19200 baud rate to work. 
31    7/91 o - Freeze mode tracing can be done on a 29050.  */
32
33
34
35 #include "defs.h"
36 #include "gdb_string.h"
37 #include "inferior.h"
38 #include "value.h"
39 #include <ctype.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <errno.h>
43 #include "terminal.h"
44 #include "target.h"
45 #include "gdbcore.h"
46
47 /* This processor is getting rusty but I am trying to keep it
48    up to date at least with data structure changes.
49    Activate this block to compile just this file.
50  */
51 #define COMPILE_CHECK 0
52 #if COMPILE_CHECK
53 #define Q_REGNUM 0
54 #define VAB_REGNUM 0
55 #define CPS_REGNUM 0
56 #define IPA_REGNUM 0
57 #define IPB_REGNUM 0
58 #define GR1_REGNUM 0
59 #define LR0_REGNUM 0
60 #define IPC_REGNUM 0
61 #define CR_REGNUM 0
62 #define BP_REGNUM 0
63 #define FC_REGNUM 0
64 #define INTE_REGNUM 0
65 #define EXO_REGNUM 0
66 #define GR96_REGNUM 0
67 #define NPC_REGNUM
68 #define FPE_REGNUM 0
69 #define PC2_REGNUM 0
70 #define FPS_REGNUM 0
71 #define ALU_REGNUM 0
72 #define LRU_REGNUM 0
73 #define TERMINAL int
74 #define RAW 1
75 #define ANYP 1
76 extern int a29k_freeze_mode;
77 extern int processor_type;
78 extern char *processor_name;
79 #endif
80
81 /* External data declarations */
82 extern int stop_soon_quietly;   /* for wait_for_inferior */
83
84 /* Forward data declarations */
85 extern struct target_ops adapt_ops;     /* Forward declaration */
86
87 /* Forward function declarations */
88 static void adapt_fetch_registers ();
89 static void adapt_store_registers ();
90 static void adapt_close ();
91 static int adapt_clear_breakpoints ();
92
93 #define FREEZE_MODE     (read_register(CPS_REGNUM) && 0x400)
94 #define USE_SHADOW_PC   ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
95
96 /* Can't seem to get binary coff working */
97 #define ASCII_COFF              /* Adapt will be downloaded with ascii coff */
98
99 /* FIXME: Replace with `set remotedebug'.  */
100 #define LOG_FILE "adapt.log"
101 #if defined (LOG_FILE)
102 FILE *log_file = NULL;
103 #endif
104
105 static int timeout = 5;
106 static char *dev_name;
107
108 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
109    adapt_open knows that we don't have a file open when the program
110    starts.  */
111 int adapt_desc = -1;
112
113 /* stream which is fdopen'd from adapt_desc.  Only valid when
114    adapt_desc != -1.  */
115 FILE *adapt_stream;
116
117 #define ON      1
118 #define OFF     0
119 static void
120 rawmode (int desc, int turnon)
121 {
122
123   TERMINAL sg;
124
125   if (desc < 0)
126     return;
127
128   ioctl (desc, TIOCGETP, &sg);
129
130   if (turnon)
131     {
132 #ifdef HAVE_TERMIO
133       sg.c_lflag &= ~(ICANON);
134 #else
135       sg.sg_flags |= RAW;
136 #endif
137     }
138   else
139     {
140 #ifdef HAVE_TERMIO
141       sg.c_lflag |= ICANON;
142 #else
143       sg.sg_flags &= ~(RAW);
144 #endif
145     }
146   ioctl (desc, TIOCSETP, &sg);
147 }
148
149 /* Suck up all the input from the adapt */
150 slurp_input (void)
151 {
152   char buf[8];
153
154 #ifdef HAVE_TERMIO
155   /* termio does the timeout for us.  */
156   while (read (adapt_desc, buf, 8) > 0);
157 #else
158   alarm (timeout);
159   while (read (adapt_desc, buf, 8) > 0);
160   alarm (0);
161 #endif
162 }
163
164 /* Read a character from the remote system, doing all the fancy
165    timeout stuff.  */
166 static int
167 readchar (void)
168 {
169   char buf;
170
171   buf = '\0';
172 #ifdef HAVE_TERMIO
173   /* termio does the timeout for us.  */
174   read (adapt_desc, &buf, 1);
175 #else
176   alarm (timeout);
177   if (read (adapt_desc, &buf, 1) < 0)
178     {
179       if (errno == EINTR)
180         error ("Timeout reading from remote system.");
181       else
182         perror_with_name ("remote");
183     }
184   alarm (0);
185 #endif
186
187   if (buf == '\0')
188     error ("Timeout reading from remote system.");
189 #if defined (LOG_FILE)
190   putc (buf & 0x7f, log_file);
191 #endif
192   return buf & 0x7f;
193 }
194
195 /* Keep discarding input from the remote system, until STRING is found. 
196    Let the user break out immediately.  */
197 static void
198 expect (char *string)
199 {
200   char *p = string;
201
202   fflush (adapt_stream);
203   immediate_quit++;
204   while (1)
205     {
206       if (readchar () == *p)
207         {
208           p++;
209           if (*p == '\0')
210             {
211               immediate_quit--;
212               return;
213             }
214         }
215       else
216         p = string;
217     }
218 }
219
220 /* Keep discarding input until we see the adapt prompt.
221
222    The convention for dealing with the prompt is that you
223    o give your command
224    o *then* wait for the prompt.
225
226    Thus the last thing that a procedure does with the serial line
227    will be an expect_prompt().  Exception:  adapt_resume does not
228    wait for the prompt, because the terminal is being handed over
229    to the inferior.  However, the next thing which happens after that
230    is a adapt_wait which does wait for the prompt.
231    Note that this includes abnormal exit, e.g. error().  This is
232    necessary to prevent getting into states from which we can't
233    recover.  */
234 static void
235 expect_prompt (void)
236 {
237 #if defined (LOG_FILE)
238   /* This is a convenient place to do this.  The idea is to do it often
239      enough that we never lose much data if we terminate abnormally.  */
240   fflush (log_file);
241 #endif
242   fflush (adapt_stream);
243   expect ("\n# ");
244 }
245
246 /* Get a hex digit from the remote system & return its value.
247    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
248 static int
249 get_hex_digit (int ignore_space)
250 {
251   int ch;
252   while (1)
253     {
254       ch = readchar ();
255       if (ch >= '0' && ch <= '9')
256         return ch - '0';
257       else if (ch >= 'A' && ch <= 'F')
258         return ch - 'A' + 10;
259       else if (ch >= 'a' && ch <= 'f')
260         return ch - 'a' + 10;
261       else if (ch == ' ' && ignore_space)
262         ;
263       else
264         {
265           expect_prompt ();
266           error ("Invalid hex digit from remote system.");
267         }
268     }
269 }
270
271 /* Get a byte from adapt_desc and put it in *BYT.  Accept any number
272    leading spaces.  */
273 static void
274 get_hex_byte (char *byt)
275 {
276   int val;
277
278   val = get_hex_digit (1) << 4;
279   val |= get_hex_digit (0);
280   *byt = val;
281 }
282
283 /* Read a 32-bit hex word from the adapt, preceded by a space  */
284 static long
285 get_hex_word (void)
286 {
287   long val;
288   int j;
289
290   val = 0;
291   for (j = 0; j < 8; j++)
292     val = (val << 4) + get_hex_digit (j == 0);
293   return val;
294 }
295 /* Get N 32-bit hex words from remote, each preceded by a space 
296    and put them in registers starting at REGNO.  */
297 static void
298 get_hex_regs (int n, int regno)
299 {
300   long val;
301   while (n--)
302     {
303       val = get_hex_word ();
304       supply_register (regno++, (char *) &val);
305     }
306 }
307 /* Called when SIGALRM signal sent due to alarm() timeout.  */
308 #ifndef HAVE_TERMIO
309
310 #ifndef __STDC__
311 #ifndef volatile
312 #define volatile
313 /**/
314 # endif
315 #endif
316 volatile int n_alarms;
317
318 void
319 adapt_timer (void)
320 {
321 #if 0
322   if (kiodebug)
323     printf ("adapt_timer called\n");
324 #endif
325   n_alarms++;
326 }
327 #endif
328
329 /* malloc'd name of the program on the remote system.  */
330 static char *prog_name = NULL;
331
332 /* Number of SIGTRAPs we need to simulate.  That is, the next
333    NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
334    SIGTRAP without actually waiting for anything.  */
335
336 static int need_artificial_trap = 0;
337
338 void
339 adapt_kill (char *arg, int from_tty)
340 {
341   fprintf (adapt_stream, "K");
342   fprintf (adapt_stream, "\r");
343   expect_prompt ();
344 }
345 /*
346  * Download a file specified in 'args', to the adapt. 
347  * FIXME: Assumes the file to download is a binary coff file.
348  */
349 static void
350 adapt_load (char *args, int fromtty)
351 {
352   FILE *fp;
353   int n;
354   char buffer[1024];
355
356   if (!adapt_stream)
357     {
358       printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
359       return;
360     }
361
362   /* OK, now read in the file.  Y=read, C=COFF, T=dTe port
363      0=start address.  */
364
365 #ifdef ASCII_COFF               /* Ascii coff */
366   fprintf (adapt_stream, "YA T,0\r");
367   fflush (adapt_stream);        /* Just in case */
368   /* FIXME: should check args for only 1 argument */
369   sprintf (buffer, "cat %s | btoa > /tmp/#adapt-btoa", args);
370   system (buffer);
371   fp = fopen ("/tmp/#adapt-btoa", "r");
372   rawmode (adapt_desc, OFF);
373   while (n = fread (buffer, 1, 1024, fp))
374     {
375       do
376         {
377           n -= write (adapt_desc, buffer, n);
378         }
379       while (n > 0);
380       if (n < 0)
381         {
382           perror ("writing ascii coff");
383           break;
384         }
385     }
386   fclose (fp);
387   rawmode (adapt_desc, ON);
388   system ("rm /tmp/#adapt-btoa");
389 #else /* Binary coff - can't get it to work . */
390   fprintf (adapt_stream, "YC T,0\r");
391   fflush (adapt_stream);        /* Just in case */
392   if (!(fp = fopen (args, "r")))
393     {
394       printf_filtered ("Can't open %s\n", args);
395       return;
396     }
397   while (n = fread (buffer, 1, 512, fp))
398     {
399       do
400         {
401           n -= write (adapt_desc, buffer, n);
402         }
403       while (n > 0);
404       if (n < 0)
405         {
406           perror ("writing ascii coff");
407           break;
408         }
409     }
410   fclose (fp);
411 #endif
412   expect_prompt ();             /* Skip garbage that comes out */
413   fprintf (adapt_stream, "\r");
414   expect_prompt ();
415 }
416
417 /* This is called not only when we first attach, but also when the
418    user types "run" after having attached.  */
419 void
420 adapt_create_inferior (char *execfile, char *args, char **env)
421 {
422   int entry_pt;
423
424   if (args && *args)
425     error ("Can't pass arguments to remote adapt process.");
426
427   if (execfile == 0 || exec_bfd == 0)
428     error ("No executable file specified");
429
430   entry_pt = (int) bfd_get_start_address (exec_bfd);
431
432   if (adapt_stream)
433     {
434       adapt_kill (NULL, NULL);
435       adapt_clear_breakpoints ();
436       init_wait_for_inferior ();
437       /* Clear the input because what the adapt sends back is different
438        * depending on whether it was running or not.
439        */
440       slurp_input ();           /* After this there should be a prompt */
441       fprintf (adapt_stream, "\r");
442       expect_prompt ();
443       printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name);
444       {
445         char buffer[10];
446         gets (buffer);
447         if (*buffer != 'n')
448           {
449             adapt_load (prog_name, 0);
450           }
451       }
452
453 #ifdef NOTDEF
454       /* Set the PC and wait for a go/cont */
455       fprintf (adapt_stream, "G %x,N\r", entry_pt);
456       printf_filtered ("Now use the 'continue' command to start.\n");
457       expect_prompt ();
458 #else
459       insert_breakpoints ();    /* Needed to get correct instruction in cache */
460       proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
461 #endif
462
463     }
464   else
465     {
466       printf_filtered ("Adapt not open yet.\n");
467     }
468 }
469
470 /* Translate baud rates from integers to damn B_codes.  Unix should
471    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
472
473 #ifndef B19200
474 #define B19200 EXTA
475 #endif
476 #ifndef B38400
477 #define B38400 EXTB
478 #endif
479
480 static struct
481 {
482   int rate, damn_b;
483 }
484 baudtab[] =
485 {
486   {
487     0, B0
488   }
489   ,
490   {
491     50, B50
492   }
493   ,
494   {
495     75, B75
496   }
497   ,
498   {
499     110, B110
500   }
501   ,
502   {
503     134, B134
504   }
505   ,
506   {
507     150, B150
508   }
509   ,
510   {
511     200, B200
512   }
513   ,
514   {
515     300, B300
516   }
517   ,
518   {
519     600, B600
520   }
521   ,
522   {
523     1200, B1200
524   }
525   ,
526   {
527     1800, B1800
528   }
529   ,
530   {
531     2400, B2400
532   }
533   ,
534   {
535     4800, B4800
536   }
537   ,
538   {
539     9600, B9600
540   }
541   ,
542   {
543     19200, B19200
544   }
545   ,
546   {
547     38400, B38400
548   }
549   ,
550   {
551     -1, -1
552   }
553   ,
554 };
555
556 static int
557 damn_b (int rate)
558 {
559   int i;
560
561   for (i = 0; baudtab[i].rate != -1; i++)
562     if (rate == baudtab[i].rate)
563       return baudtab[i].damn_b;
564   return B38400;                /* Random */
565 }
566
567
568 /* Open a connection to a remote debugger.
569    NAME is the filename used for communication, then a space,
570    then the baud rate.
571  */
572
573 static int baudrate = 9600;
574 static void
575 adapt_open (char *name, int from_tty)
576 {
577   TERMINAL sg;
578   unsigned int prl;
579   char *p;
580
581   /* Find the first whitespace character, it separates dev_name from
582      prog_name.  */
583   if (name == 0)
584     goto erroid;
585
586   for (p = name;
587        *p != '\0' && !isspace (*p); p++)
588     ;
589   if (*p == '\0')
590   erroid:
591     error ("\
592 Please include the name of the device for the serial port,\n\
593 the baud rate, and the name of the program to run on the remote system.");
594   dev_name = (char *) xmalloc (p - name + 1);
595   strncpy (dev_name, name, p - name);
596   dev_name[p - name] = '\0';
597
598   /* Skip over the whitespace after dev_name */
599   for (; isspace (*p); p++)
600     /*EMPTY */ ;
601
602   if (1 != sscanf (p, "%d ", &baudrate))
603     goto erroid;
604
605   /* Skip the number and then the spaces */
606   for (; isdigit (*p); p++)
607     /*EMPTY */ ;
608   for (; isspace (*p); p++)
609     /*EMPTY */ ;
610
611   if (prog_name != NULL)
612     xfree (prog_name);
613   prog_name = savestring (p, strlen (p));
614
615   adapt_close (0);
616
617   adapt_desc = open (dev_name, O_RDWR);
618   if (adapt_desc < 0)
619     perror_with_name (dev_name);
620   ioctl (adapt_desc, TIOCGETP, &sg);
621 #if ! defined(COMPILE_CHECK)
622 #ifdef HAVE_TERMIO
623   sg.c_cc[VMIN] = 0;            /* read with timeout.  */
624   sg.c_cc[VTIME] = timeout * 10;
625   sg.c_lflag &= ~(ICANON | ECHO);
626   sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
627 #else
628   sg.sg_ispeed = damn_b (baudrate);
629   sg.sg_ospeed = damn_b (baudrate);
630   sg.sg_flags |= RAW | ANYP;
631   sg.sg_flags &= ~ECHO;
632 #endif
633
634   ioctl (adapt_desc, TIOCSETP, &sg);
635   adapt_stream = fdopen (adapt_desc, "r+");
636 #endif /* compile_check */
637   push_target (&adapt_ops);
638
639 #ifndef HAVE_TERMIO
640 #ifndef NO_SIGINTERRUPT
641   /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
642      the read.  */
643   if (siginterrupt (SIGALRM, 1) != 0)
644     perror ("adapt_open: error in siginterrupt");
645 #endif
646
647   /* Set up read timeout timer.  */
648   if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
649     perror ("adapt_open: error in signal");
650 #endif
651
652 #if defined (LOG_FILE)
653   log_file = fopen (LOG_FILE, "w");
654   if (log_file == NULL)
655     perror_with_name (LOG_FILE);
656 #endif
657
658   /* Put this port into NORMAL mode, send the 'normal' character */
659   write (adapt_desc, "\ 1", 1);   /* Control A */
660   write (adapt_desc, "\r", 1);
661   expect_prompt ();
662
663   /* Hello?  Are you there?  */
664   write (adapt_desc, "\r", 1);
665
666   expect_prompt ();
667
668   /* Clear any break points */
669   adapt_clear_breakpoints ();
670
671   /* Print out some stuff, letting the user now what's going on */
672   printf_filtered ("Connected to an Adapt via %s.\n", dev_name);
673   /* FIXME: can this restriction be removed? */
674   printf_filtered ("Remote debugging using virtual addresses works only\n");
675   printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n");
676   if (processor_type != a29k_freeze_mode)
677     {
678       fprintf_filtered (gdb_stderr,
679                         "Freeze-mode debugging not available, and can only be done on an A29050.\n");
680     }
681 }
682
683 /* Close out all files and local state before this target loses control. */
684
685 static void
686 adapt_close (int quitting)
687 {
688
689   /* Clear any break points */
690   adapt_clear_breakpoints ();
691
692   /* Put this port back into REMOTE mode */
693   if (adapt_stream)
694     {
695       fflush (adapt_stream);
696       sleep (1);                /* Let any output make it all the way back */
697       write (adapt_desc, "R\r", 2);
698     }
699
700   /* Due to a bug in Unix, fclose closes not only the stdio stream,
701      but also the file descriptor.  So we don't actually close
702      adapt_desc.  */
703   if (adapt_stream)
704     fclose (adapt_stream);      /* This also closes adapt_desc */
705   if (adapt_desc >= 0)
706     /* close (adapt_desc); */
707
708     /* Do not try to close adapt_desc again, later in the program.  */
709     adapt_stream = NULL;
710   adapt_desc = -1;
711
712 #if defined (LOG_FILE)
713   if (log_file)
714     {
715       if (ferror (log_file))
716         printf_filtered ("Error writing log file.\n");
717       if (fclose (log_file) != 0)
718         printf_filtered ("Error closing log file.\n");
719       log_file = NULL;
720     }
721 #endif
722 }
723
724 /* Attach to the target that is already loaded and possibly running */
725 static void
726 adapt_attach (char *args, int from_tty)
727 {
728
729   if (from_tty)
730     printf_filtered ("Attaching to remote program %s.\n", prog_name);
731
732   /* Send the adapt a kill. It is ok if it is not already running */
733   fprintf (adapt_stream, "K\r");
734   fflush (adapt_stream);
735   expect_prompt ();             /* Slurp the echo */
736 }
737
738
739 /* Terminate the open connection to the remote debugger.
740    Use this when you want to detach and do something else
741    with your gdb.  */
742 void
743 adapt_detach (char *args, int from_tty)
744 {
745
746   if (adapt_stream)
747     {                           /* Send it on its way (tell it to continue)  */
748       adapt_clear_breakpoints ();
749       fprintf (adapt_stream, "G\r");
750     }
751
752   pop_target ();                /* calls adapt_close to do the real work */
753   if (from_tty)
754     printf_filtered ("Ending remote %s debugging\n", target_shortname);
755 }
756
757 /* Tell the remote machine to resume.  */
758
759 void
760 adapt_resume (int pid, int step, enum target_signal sig)
761 {
762   if (step)
763     {
764       write (adapt_desc, "t 1,s\r", 6);
765       /* Wait for the echo.  */
766       expect ("t 1,s\r\n");
767       /* Then comes a line containing the instruction we stepped to.  */
768       expect ("@");
769       /* Then we get the prompt.  */
770       expect_prompt ();
771
772       /* Force the next adapt_wait to return a trap.  Not doing anything
773          about I/O from the target means that the user has to type
774          "continue" to see any.  FIXME, this should be fixed.  */
775       need_artificial_trap = 1;
776     }
777   else
778     {
779       write (adapt_desc, "G\r", 2);
780       /* Swallow the echo.  */
781       expect_prompt ();
782     }
783 }
784
785 /* Wait until the remote machine stops, then return,
786    storing status in STATUS just as `wait' would.  */
787
788 int
789 adapt_wait (struct target_waitstatus *status)
790 {
791   /* Strings to look for.  '?' means match any single character.  
792      Note that with the algorithm we use, the initial character
793      of the string cannot recur in the string, or we will not
794      find some cases of the string in the input.  */
795
796   static char bpt[] = "@";
797   /* It would be tempting to look for "\n[__exit + 0x8]\n"
798      but that requires loading symbols with "yc i" and even if
799      we did do that we don't know that the file has symbols.  */
800   static char exitmsg[] = "@????????I    JMPTI     GR121,LR0";
801   char *bp = bpt;
802   char *ep = exitmsg;
803
804   /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
805   char swallowed[50];
806   /* Current position in swallowed.  */
807   char *swallowed_p = swallowed;
808
809   int ch;
810   int ch_handled;
811   int old_timeout = timeout;
812   int old_immediate_quit = immediate_quit;
813
814   status->kind = TARGET_WAITKIND_EXITED;
815   status->value.integer = 0;
816
817   if (need_artificial_trap != 0)
818     {
819       status->kind = TARGET_WAITKIND_STOPPED;
820       status->value.sig = TARGET_SIGNAL_TRAP;
821       need_artificial_trap--;
822       return 0;
823     }
824
825   timeout = 0;                  /* Don't time out -- user program is running. */
826   immediate_quit = 1;           /* Helps ability to QUIT */
827   while (1)
828     {
829       QUIT;                     /* Let user quit and leave process running */
830       ch_handled = 0;
831       ch = readchar ();
832       if (ch == *bp)
833         {
834           bp++;
835           if (*bp == '\0')
836             break;
837           ch_handled = 1;
838
839           *swallowed_p++ = ch;
840         }
841       else
842         bp = bpt;
843       if (ch == *ep || *ep == '?')
844         {
845           ep++;
846           if (*ep == '\0')
847             break;
848
849           if (!ch_handled)
850             *swallowed_p++ = ch;
851           ch_handled = 1;
852         }
853       else
854         ep = exitmsg;
855       if (!ch_handled)
856         {
857           char *p;
858           /* Print out any characters which have been swallowed.  */
859           for (p = swallowed; p < swallowed_p; ++p)
860             putc (*p, stdout);
861           swallowed_p = swallowed;
862           putc (ch, stdout);
863         }
864     }
865   expect_prompt ();
866   if (*bp == '\0')
867     {
868       status->kind = TARGET_WAITKIND_STOPPED;
869       status->value.sig = TARGET_SIGNAL_TRAP;
870     }
871   else
872     {
873       status->kind = TARGET_WAITKIND_EXITED;
874       status->value.integer = 0;
875     }
876   timeout = old_timeout;
877   immediate_quit = old_immediate_quit;
878   return 0;
879 }
880
881 /* Return the name of register number REGNO
882    in the form input and output by adapt.
883
884    Returns a pointer to a static buffer containing the answer.  */
885 static char *
886 get_reg_name (int regno)
887 {
888   static char buf[80];
889   if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
890     sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
891 #if defined(GR64_REGNUM)
892   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
893     sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
894 #endif
895   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
896     sprintf (buf, "LR%03d", regno - LR0_REGNUM);
897   else if (regno == Q_REGNUM)
898     strcpy (buf, "SR131");
899   else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
900     sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
901   else if (regno == ALU_REGNUM)
902     strcpy (buf, "SR132");
903   else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
904     sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
905   else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
906     {
907       /* When a 29050 is in freeze-mode, read shadow pcs instead */
908       if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
909         sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
910       else
911         sprintf (buf, "SR%03d", regno - VAB_REGNUM);
912     }
913   else if (regno == GR1_REGNUM)
914     strcpy (buf, "GR001");
915   return buf;
916 }
917
918 /* Read the remote registers.  */
919
920 static void
921 adapt_fetch_registers (void)
922 {
923   int reg_index;
924   int regnum_index;
925   char tempbuf[10];
926   int sreg_buf[16];
927   int i, j;
928
929 /* 
930  * Global registers
931  */
932 #if defined(GR64_REGNUM)
933   write (adapt_desc, "dw gr64,gr95\r", 13);
934   for (reg_index = 64, regnum_index = GR64_REGNUM;
935        reg_index < 96;
936        reg_index += 4, regnum_index += 4)
937     {
938       sprintf (tempbuf, "GR%03d ", reg_index);
939       expect (tempbuf);
940       get_hex_regs (4, regnum_index);
941       expect ("\n");
942     }
943 #endif
944   write (adapt_desc, "dw gr96,gr127\r", 14);
945   for (reg_index = 96, regnum_index = GR96_REGNUM;
946        reg_index < 128;
947        reg_index += 4, regnum_index += 4)
948     {
949       sprintf (tempbuf, "GR%03d ", reg_index);
950       expect (tempbuf);
951       get_hex_regs (4, regnum_index);
952       expect ("\n");
953     }
954
955 /* 
956  * Local registers
957  */
958   for (i = 0; i < 128; i += 32)
959     {
960       /* The PC has a tendency to hang if we get these
961          all in one fell swoop ("dw lr0,lr127").  */
962       sprintf (tempbuf, "dw lr%d\r", i);
963       write (adapt_desc, tempbuf, strlen (tempbuf));
964       for (reg_index = i, regnum_index = LR0_REGNUM + i;
965            reg_index < i + 32;
966            reg_index += 4, regnum_index += 4)
967         {
968           sprintf (tempbuf, "LR%03d ", reg_index);
969           expect (tempbuf);
970           get_hex_regs (4, regnum_index);
971           expect ("\n");
972         }
973     }
974
975 /* 
976  * Special registers
977  */
978   sprintf (tempbuf, "dw sr0\r");
979   write (adapt_desc, tempbuf, strlen (tempbuf));
980   for (i = 0; i < 4; i++)
981     {                           /* SR0 - SR14 */
982       sprintf (tempbuf, "SR%3d", i * 4);
983       expect (tempbuf);
984       for (j = 0; j < (i == 3 ? 3 : 4); j++)
985         sreg_buf[i * 4 + j] = get_hex_word ();
986     }
987   expect_prompt ();
988   /* 
989    * Read the pcs individually if we are in freeze mode.
990    * See get_reg_name(), it translates the register names for the pcs to
991    * the names of the shadow pcs.
992    */
993   if (USE_SHADOW_PC)
994     {
995       sreg_buf[10] = read_register (NPC_REGNUM);        /* pc0 */
996       sreg_buf[11] = read_register (PC_REGNUM);         /* pc1 */
997       sreg_buf[12] = read_register (PC2_REGNUM);        /* pc2 */
998     }
999   for (i = 0; i < 14; i++)      /* Supply vab -> lru */
1000     supply_register (VAB_REGNUM + i, (char *) &sreg_buf[i]);
1001   sprintf (tempbuf, "dw sr128\r");
1002   write (adapt_desc, tempbuf, strlen (tempbuf));
1003   for (i = 0; i < 2; i++)
1004     {                           /* SR128 - SR135 */
1005       sprintf (tempbuf, "SR%3d", 128 + i * 4);
1006       expect (tempbuf);
1007       for (j = 0; j < 4; j++)
1008         sreg_buf[i * 4 + j] = get_hex_word ();
1009     }
1010   expect_prompt ();
1011   supply_register (IPC_REGNUM, (char *) &sreg_buf[0]);
1012   supply_register (IPA_REGNUM, (char *) &sreg_buf[1]);
1013   supply_register (IPB_REGNUM, (char *) &sreg_buf[2]);
1014   supply_register (Q_REGNUM, (char *) &sreg_buf[3]);
1015   /* Skip ALU */
1016   supply_register (BP_REGNUM, (char *) &sreg_buf[5]);
1017   supply_register (FC_REGNUM, (char *) &sreg_buf[6]);
1018   supply_register (CR_REGNUM, (char *) &sreg_buf[7]);
1019
1020   /* There doesn't seem to be any way to get these.  */
1021   {
1022     int val = -1;
1023     supply_register (FPE_REGNUM, (char *) &val);
1024     supply_register (INTE_REGNUM, (char *) &val);
1025     supply_register (FPS_REGNUM, (char *) &val);
1026     supply_register (EXO_REGNUM, (char *) &val);
1027   }
1028
1029   write (adapt_desc, "dw gr1,gr1\r", 11);
1030   expect ("GR001 ");
1031   get_hex_regs (1, GR1_REGNUM);
1032   expect_prompt ();
1033 }
1034
1035 /* Fetch register REGNO, or all registers if REGNO is -1.
1036  */
1037 static void
1038 adapt_fetch_register (int regno)
1039 {
1040   if (regno == -1)
1041     adapt_fetch_registers ();
1042   else
1043     {
1044       char *name = get_reg_name (regno);
1045       fprintf (adapt_stream, "dw %s,%s\r", name, name);
1046       expect (name);
1047       expect (" ");
1048       get_hex_regs (1, regno);
1049       expect_prompt ();
1050     }
1051 }
1052
1053 /* Store the remote registers from the contents of the block REGS.  */
1054
1055 static void
1056 adapt_store_registers (void)
1057 {
1058   int i, j;
1059
1060   fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1061   expect_prompt ();
1062
1063 #if defined(GR64_REGNUM)
1064   for (j = 0; j < 32; j += 16)
1065     {
1066       fprintf (adapt_stream, "s gr%d,", j + 64);
1067       for (i = 0; i < 15; ++i)
1068         fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1069       fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1070       expect_prompt ();
1071     }
1072 #endif
1073   for (j = 0; j < 32; j += 16)
1074     {
1075       fprintf (adapt_stream, "s gr%d,", j + 96);
1076       for (i = 0; i < 15; ++i)
1077         fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1078       fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1079       expect_prompt ();
1080     }
1081
1082   for (j = 0; j < 128; j += 16)
1083     {
1084       fprintf (adapt_stream, "s lr%d,", j);
1085       for (i = 0; i < 15; ++i)
1086         fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1087       fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1088       expect_prompt ();
1089     }
1090
1091   fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1092            read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1093   expect_prompt ();
1094   fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1095            read_register (FC_REGNUM), read_register (CR_REGNUM));
1096   expect_prompt ();
1097   fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1098   expect_prompt ();
1099   fprintf (adapt_stream, "s sr0,");
1100   for (i = 0; i < 7; ++i)
1101     fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1102   expect_prompt ();
1103   fprintf (adapt_stream, "s sr7,");
1104   for (i = 7; i < 14; ++i)
1105     fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1106   expect_prompt ();
1107 }
1108
1109 /* Store register REGNO, or all if REGNO == -1.
1110    Return errno value.  */
1111 void
1112 adapt_store_register (int regno)
1113 {
1114   /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1115   if (regno == -1)
1116     adapt_store_registers ();
1117   else
1118     {
1119       char *name = get_reg_name (regno);
1120       fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1121       /* Setting GR1 changes the numbers of all the locals, so
1122          invalidate the register cache.  Do this *after* calling
1123          read_register, because we want read_register to return the
1124          value that write_register has just stuffed into the registers
1125          array, not the value of the register fetched from the
1126          inferior.  */
1127       if (regno == GR1_REGNUM)
1128         registers_changed ();
1129       expect_prompt ();
1130     }
1131 }
1132
1133 /* Get ready to modify the registers array.  On machines which store
1134    individual registers, this doesn't need to do anything.  On machines
1135    which store all the registers in one fell swoop, this makes sure
1136    that registers contains all the registers from the program being
1137    debugged.  */
1138
1139 void
1140 adapt_prepare_to_store (void)
1141 {
1142   /* Do nothing, since we can store individual regs */
1143 }
1144
1145 static CORE_ADDR
1146 translate_addr (CORE_ADDR addr)
1147 {
1148 #if defined(KERNEL_DEBUGGING)
1149   /* Check for a virtual address in the kernel */
1150   /* Assume physical address of ublock is in  paddr_u register */
1151   if (addr >= UVADDR)
1152     {
1153       /* PADDR_U register holds the physical address of the ublock */
1154       CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
1155       return (i + addr - (CORE_ADDR) UVADDR);
1156     }
1157   else
1158     {
1159       return (addr);
1160     }
1161 #else
1162   return (addr);
1163 #endif
1164 }
1165
1166
1167 /* FIXME!  Merge these two.  */
1168 int
1169 adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
1170                             struct mem_attrib *attrib ATTRIBUTE_UNUSED,
1171                             struct target_ops *target ATTRIBUTE_UNUSED)
1172 {
1173
1174   memaddr = translate_addr (memaddr);
1175
1176   if (write)
1177     return adapt_write_inferior_memory (memaddr, myaddr, len);
1178   else
1179     return adapt_read_inferior_memory (memaddr, myaddr, len);
1180 }
1181
1182 void
1183 adapt_files_info (void)
1184 {
1185   printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1186                    dev_name, baudrate, prog_name);
1187   printf_filtered ("\ton an %s processor.\n", processor_name[processor_type]);
1188 }
1189
1190 /* Copy LEN bytes of data from debugger memory at MYADDR
1191    to inferior's memory at MEMADDR.  Returns errno value.  
1192    * sb/sh instructions don't work on unaligned addresses, when TU=1. 
1193  */
1194 int
1195 adapt_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1196 {
1197   int i;
1198   unsigned int cps;
1199
1200   /* Turn TU bit off so we can do 'sb' commands */
1201   cps = read_register (CPS_REGNUM);
1202   if (cps & 0x00000800)
1203     write_register (CPS_REGNUM, cps & ~(0x00000800));
1204
1205   for (i = 0; i < len; i++)
1206     {
1207       if ((i % 16) == 0)
1208         fprintf (adapt_stream, "sb %x,", memaddr + i);
1209       if ((i % 16) == 15 || i == len - 1)
1210         {
1211           fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]);
1212           expect_prompt ();
1213         }
1214       else
1215         fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]);
1216     }
1217   /* Restore the old value of cps if the TU bit was on */
1218   if (cps & 0x00000800)
1219     write_register (CPS_REGNUM, cps);
1220   return len;
1221 }
1222
1223 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1224    at debugger address MYADDR.  Returns errno value.  */
1225 int
1226 adapt_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1227 {
1228   int i;
1229
1230   /* Number of bytes read so far.  */
1231   int count;
1232
1233   /* Starting address of this pass.  */
1234   unsigned long startaddr;
1235
1236   /* Number of bytes to read in this pass.  */
1237   int len_this_pass;
1238
1239   /* Note that this code works correctly if startaddr is just less
1240      than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1241      thing).  That is, something like
1242      adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1243      works--it never adds len to memaddr and gets 0.  */
1244   /* However, something like
1245      adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1246      doesn't need to work.  Detect it and give up if there's an attempt
1247      to do that.  */
1248
1249   if (((memaddr - 1) + len) < memaddr)
1250     return EIO;
1251
1252   startaddr = memaddr;
1253   count = 0;
1254   while (count < len)
1255     {
1256       len_this_pass = 16;
1257       if ((startaddr % 16) != 0)
1258         len_this_pass -= startaddr % 16;
1259       if (len_this_pass > (len - count))
1260         len_this_pass = (len - count);
1261
1262       fprintf (adapt_stream, "db %x,%x\r", startaddr,
1263                (startaddr - 1) + len_this_pass);
1264
1265 #ifdef NOTDEF                   /* Why do this */
1266       expect ("\n");
1267       /* Look for 8 hex digits.  */
1268       i = 0;
1269       while (1)
1270         {
1271           if (isxdigit (readchar ()))
1272             ++i;
1273           else
1274             {
1275               expect_prompt ();
1276               error ("Hex digit expected from remote system.");
1277             }
1278           if (i >= 8)
1279             break;
1280         }
1281 #endif /* NOTDEF */
1282
1283       expect ("  ");
1284
1285       for (i = 0; i < len_this_pass; i++)
1286         get_hex_byte (&myaddr[count++]);
1287
1288       expect_prompt ();
1289
1290       startaddr += len_this_pass;
1291     }
1292   return count;
1293 }
1294
1295 #define MAX_BREAKS      8
1296 static int num_brkpts = 0;
1297
1298 /* Insert a breakpoint at ADDR.  SAVE is normally the address of the
1299    pattern buffer where the instruction that the breakpoint overwrites
1300    is saved.  It is unused here since the Adapt Monitor is responsible
1301    for saving/restoring the original instruction. */
1302
1303 static int
1304 adapt_insert_breakpoint (CORE_ADDR addr, char *save)
1305 {
1306   if (num_brkpts < MAX_BREAKS)
1307     {
1308       num_brkpts++;
1309       fprintf (adapt_stream, "B %x", addr);
1310       fprintf (adapt_stream, "\r");
1311       expect_prompt ();
1312       return (0);               /* Success */
1313     }
1314   else
1315     {
1316       fprintf_filtered (gdb_stderr,
1317                       "Too many break points, break point not installed\n");
1318       return (1);               /* Failure */
1319     }
1320
1321 }
1322
1323 /* Remove a breakpoint at ADDR.  SAVE is normally the previously
1324    saved pattern, but is unused here as the Adapt Monitor is
1325    responsible for saving/restoring instructions. */
1326
1327 static int
1328 adapt_remove_breakpoint (CORE_ADDR addr, char *save)
1329 {
1330   if (num_brkpts > 0)
1331     {
1332       num_brkpts--;
1333       fprintf (adapt_stream, "BR %x", addr);
1334       fprintf (adapt_stream, "\r");
1335       fflush (adapt_stream);
1336       expect_prompt ();
1337     }
1338   return (0);
1339 }
1340
1341 /* Clear the adapts notion of what the break points are */
1342 static int
1343 adapt_clear_breakpoints (void)
1344 {
1345   if (adapt_stream)
1346     {
1347       fprintf (adapt_stream, "BR");     /* Clear all break points */
1348       fprintf (adapt_stream, "\r");
1349       fflush (adapt_stream);
1350       expect_prompt ();
1351     }
1352   num_brkpts = 0;
1353 }
1354 static void
1355 adapt_mourn (void)
1356 {
1357   adapt_clear_breakpoints ();
1358   pop_target ();                /* Pop back to no-child state */
1359   generic_mourn_inferior ();
1360 }
1361
1362 /* Display everthing we read in from the adapt until we match/see the
1363  * specified string
1364  */
1365 static int
1366 display_until (char *str)
1367 {
1368   int i = 0, j, c;
1369
1370   while (c = readchar ())
1371     {
1372       if (c == str[i])
1373         {
1374           i++;
1375           if (i == strlen (str))
1376             return;
1377         }
1378       else
1379         {
1380           if (i)
1381             {
1382               for (j = 0; j < i; j++)   /* Put everthing we matched */
1383                 putchar (str[j]);
1384               i = 0;
1385             }
1386           putchar (c);
1387         }
1388     }
1389
1390 }
1391
1392
1393 /* Put a command string, in args, out to the adapt.  The adapt is assumed to
1394    be in raw mode, all writing/reading done through adapt_desc.
1395    Ouput from the adapt is placed on the users terminal until the
1396    prompt from the adapt is seen.
1397    FIXME: Can't handle commands that take input.  */
1398
1399 void
1400 adapt_com (char *args, int fromtty)
1401 {
1402   if (!adapt_stream)
1403     {
1404       printf_filtered ("Adapt not open.  Use the 'target' command to open.\n");
1405       return;
1406     }
1407
1408   /* Clear all input so only command relative output is displayed */
1409   slurp_input ();
1410
1411   switch (islower (args[0]) ? toupper (args[0]) : args[0])
1412     {
1413     default:
1414       printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args);
1415       break;
1416     case 'G':                   /* Go, begin execution */
1417       write (adapt_desc, args, strlen (args));
1418       write (adapt_desc, "\r", 1);
1419       expect_prompt ();
1420       break;
1421     case 'B':                   /* Break points, B or BR */
1422     case 'C':                   /* Check current 29k status (running/halted) */
1423     case 'D':                   /* Display data/registers */
1424     case 'I':                   /* Input from i/o space */
1425     case 'J':                   /* Jam an instruction */
1426     case 'K':                   /* Kill, stop execution */
1427     case 'L':                   /* Disassemble */
1428     case 'O':                   /* Output to i/o space */
1429     case 'T':                   /* Trace */
1430     case 'P':                   /* Pulse an input line */
1431     case 'X':                   /* Examine special purpose registers */
1432     case 'Z':                   /* Display trace buffer */
1433       write (adapt_desc, args, strlen (args));
1434       write (adapt_desc, "\r", 1);
1435       expect (args);            /* Don't display the command */
1436       display_until ("# ");
1437       break;
1438       /* Begin commands that take input in the form 'c x,y[,z...]' */
1439     case 'S':                   /* Set memory or register */
1440       if (strchr (args, ','))
1441         {                       /* Assume it is properly formatted */
1442           write (adapt_desc, args, strlen (args));
1443           write (adapt_desc, "\r", 1);
1444           expect_prompt ();
1445         }
1446       break;
1447     }
1448 }
1449
1450 /* Define the target subroutine names */
1451
1452 struct target_ops adapt_ops;
1453
1454 static void
1455 init_adapt_ops (void)
1456 {
1457   adapt_ops.to_shortname = "adapt";
1458   adapt_ops.to_longname = "Remote AMD `Adapt' target";
1459   adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1460   adapt_ops.to_open = adapt_open;
1461   adapt_ops.to_close = adapt_close;
1462   adapt_ops.to_attach = adapt_attach;
1463   adapt_ops.to_post_attach = NULL;
1464   adapt_ops.to_require_attach = NULL;
1465   adapt_ops.to_detach = adapt_detach;
1466   adapt_ops.to_require_detach = NULL;
1467   adapt_ops.to_resume = adapt_resume;
1468   adapt_ops.to_wait = adapt_wait;
1469   adapt_ops.to_post_wait = NULL;
1470   adapt_ops.to_fetch_registers = adapt_fetch_register;
1471   adapt_ops.to_store_registers = adapt_store_register;
1472   adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
1473   adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1474   adapt_ops.to_files_info = adapt_files_info;
1475   adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
1476   adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
1477   adapt_ops.to_terminal_init = 0;
1478   adapt_ops.to_terminal_inferior = 0;
1479   adapt_ops.to_terminal_ours_for_output = 0;
1480   adapt_ops.to_terminal_ours = 0;
1481   adapt_ops.to_terminal_info = 0;
1482   adapt_ops.to_kill = adapt_kill;
1483   adapt_ops.to_load = adapt_load;
1484   adapt_ops.to_lookup_symbol = 0;
1485   adapt_ops.to_create_inferior = adapt_create_inferior;
1486   adapt_ops.to_post_startup_inferior = NULL;
1487   adapt_ops.to_acknowledge_created_inferior = NULL;
1488   adapt_ops.to_clone_and_follow_inferior = NULL;
1489   adapt_ops.to_post_follow_inferior_by_clone = NULL;
1490   adapt_ops.to_insert_fork_catchpoint = NULL;
1491   adapt_ops.to_remove_fork_catchpoint = NULL;
1492   adapt_ops.to_insert_vfork_catchpoint = NULL;
1493   adapt_ops.to_remove_vfork_catchpoint = NULL;
1494   adapt_ops.to_has_forked = NULL;
1495   adapt_ops.to_has_vforked = NULL;
1496   adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1497   adapt_ops.to_post_follow_vfork = NULL;
1498   adapt_ops.to_insert_exec_catchpoint = NULL;
1499   adapt_ops.to_remove_exec_catchpoint = NULL;
1500   adapt_ops.to_has_execd = NULL;
1501   adapt_ops.to_reported_exec_events_per_exec_call = NULL;
1502   adapt_ops.to_has_exited = NULL;
1503   adapt_ops.to_mourn_inferior = adapt_mourn;
1504   adapt_ops.to_can_run = 0;
1505   adapt_ops.to_notice_signals = 0;
1506   adapt_ops.to_thread_alive = 0;
1507   adapt_ops.to_stop = 0;        /* process_stratum; */
1508   adapt_ops.to_pid_to_exec_file = NULL;
1509   adapt_ops.to_core_file_to_sym_file = NULL;
1510   adapt_ops.to_stratum = 0;
1511   adapt_ops.DONT_USE = 0;
1512   adapt_ops.to_has_all_memory = 1;
1513   adapt_ops.to_has_memory = 1;
1514   adapt_ops.to_has_stack = 1;
1515   adapt_ops.to_has_registers = 1;
1516   adapt_ops.to_has_execution = 0;
1517   adapt_ops.to_sections = 0;
1518   adapt_ops.to_sections_end = 0;
1519   adapt_ops.to_magic = OPS_MAGIC;
1520 }                               /* init_adapt_ops */
1521
1522 void
1523 _initialize_remote_adapt (void)
1524 {
1525   init_adapt_ops ();
1526   add_target (&adapt_ops);
1527   add_com ("adapt <command>", class_obscure, adapt_com,
1528            "Send a command to the AMD Adapt remote monitor.");
1529 }