9ca6167ce023065b28b4d31999aa0e25fb4f9a3b
[deliverable/binutils-gdb.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 }
This page took 0.060304 seconds and 3 git commands to generate.