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