]> Git Repo - binutils.git/blob - gdb/rem-multi.shar
ansi name abuse changes
[binutils.git] / gdb / rem-multi.shar
1 #!/bin/sh
2 #       This is a shell archive.
3 #       Run the file through sh to extract its contents.
4 # shar: Shell Archiver
5 #       Run the following text with /bin/sh to create:
6 #       Remote_Makefile
7 #       remote_gutils.c
8 #       remote_inflow.c
9 #       remote_server.c
10 #       remote_utils.c
11 # This archive created: Fri Jun 23 17:06:55 1989
12 cat << \SHAR_EOF > Remote_Makefile
13 #    Makefile for the remote server for GDB, the GNU debugger.
14 #    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
15
16 # This file is part of GDB.
17
18 # This program is free software; you can redistribute it and/or modify
19 # it under the terms of the GNU General Public License as published by
20 # the Free Software Foundation; either version 2 of the License, or
21 # (at your option) any later version.
22
23 # This program is distributed in the hope that it will be useful,
24 # but WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 # GNU General Public License for more details.
27
28 # You should have received a copy of the GNU General Public License
29 # along with this program; if not, write to the Free Software
30 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
32 CFLAGS = -g 
33 CC = cc
34
35 SERVER = remote_server.o\
36                  remote_inflow.o\
37                  remote_utils.o\
38                  remote_gutils.o 
39
40 prog : $(SERVER)
41         $(CC) -g -o serve $(SERVER) 
42 SHAR_EOF
43 cat << \SHAR_EOF > remote_gutils.c
44 /* General utility routines for the remote server for GDB, the GNU debugger.
45    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
46
47 This file is part of GDB.
48
49 This program is free software; you can redistribute it and/or modify
50 it under the terms of the GNU General Public License as published by
51 the Free Software Foundation; either version 2 of the License, or
52 (at your option) any later version.
53
54 This program is distributed in the hope that it will be useful,
55 but WITHOUT ANY WARRANTY; without even the implied warranty of
56 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57 GNU General Public License for more details.
58
59 You should have received a copy of the GNU General Public License
60 along with this program; if not, write to the Free Software
61 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
62
63 #include <stdio.h>
64 #include <sys/ioctl.h>
65 #include "defs.h"
66
67 void error ();
68 void fatal ();
69
70 /* Chain of cleanup actions established with make_cleanup,
71    to be executed if an error happens.  */
72
73 static struct cleanup *cleanup_chain;
74
75 /* Nonzero means a quit has been requested.  */
76
77 int quit_flag;
78
79 /* Nonzero means quit immediately if Control-C is typed now,
80    rather than waiting until QUIT is executed.  */
81
82 int immediate_quit;
83 \f
84 /* Add a new cleanup to the cleanup_chain,
85    and return the previous chain pointer
86    to be passed later to do_cleanups or discard_cleanups.
87    Args are FUNCTION to clean up with, and ARG to pass to it.  */
88
89 struct cleanup *
90 make_cleanup (function, arg)
91      void (*function) ();
92      int arg;
93 {
94   register struct cleanup *new
95     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
96   register struct cleanup *old_chain = cleanup_chain;
97
98   new->next = cleanup_chain;
99   new->function = function;
100   new->arg = arg;
101   cleanup_chain = new;
102
103   return old_chain;
104 }
105
106 /* Discard cleanups and do the actions they describe
107    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
108
109 void
110 do_cleanups (old_chain)
111      register struct cleanup *old_chain;
112 {
113   register struct cleanup *ptr;
114   while ((ptr = cleanup_chain) != old_chain)
115     {
116       (*ptr->function) (ptr->arg);
117       cleanup_chain = ptr->next;
118       free (ptr);
119     }
120 }
121
122 /* Discard cleanups, not doing the actions they describe,
123    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
124
125 void
126 discard_cleanups (old_chain)
127      register struct cleanup *old_chain;
128 {
129   register struct cleanup *ptr;
130   while ((ptr = cleanup_chain) != old_chain)
131     {
132       cleanup_chain = ptr->next;
133       free (ptr);
134     }
135 }
136
137 /* This function is useful for cleanups.
138    Do
139
140      foo = xmalloc (...);
141      old_chain = make_cleanup (free_current_contents, &foo);
142
143    to arrange to free the object thus allocated.  */
144
145 void
146 free_current_contents (location)
147      char **location;
148 {
149   free (*location);
150 }
151 \f
152 /* Generally useful subroutines used throughout the program.  */
153
154 /* Like malloc but get error if no storage available.  */
155
156 char *
157 xmalloc (size)
158      long size;
159 {
160   register char *val = (char *) malloc (size);
161   if (!val)
162     fatal ("virtual memory exhausted.", 0);
163   return val;
164 }
165
166 /* Like realloc but get error if no storage available.  */
167
168 char *
169 xrealloc (ptr, size)
170      char *ptr;
171      long size;
172 {
173   register char *val = (char *) realloc (ptr, size);
174   if (!val)
175     fatal ("virtual memory exhausted.", 0);
176   return val;
177 }
178
179 /* Print the system error message for errno, and also mention STRING
180    as the file name for which the error was encountered.
181    Then return to command level.  */
182
183 void
184 perror_with_name (string)
185      char *string;
186 {
187   extern int sys_nerr;
188   extern char *sys_errlist[];
189   extern int errno;
190   char *err;
191   char *combined;
192
193   if (errno < sys_nerr)
194     err = sys_errlist[errno];
195   else
196     err = "unknown error";
197
198   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
199   strcpy (combined, string);
200   strcat (combined, ": ");
201   strcat (combined, err);
202
203   error ("%s.", combined);
204 }
205
206 /* Print the system error message for ERRCODE, and also mention STRING
207    as the file name for which the error was encountered.  */
208
209 void
210 print_sys_errmsg (string, errcode)
211      char *string;
212      int errcode;
213 {
214   extern int sys_nerr;
215   extern char *sys_errlist[];
216   char *err;
217   char *combined;
218
219   if (errcode < sys_nerr)
220     err = sys_errlist[errcode];
221   else
222     err = "unknown error";
223
224   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
225   strcpy (combined, string);
226   strcat (combined, ": ");
227   strcat (combined, err);
228
229   printf ("%s.\n", combined);
230 }
231
232 void
233 quit ()
234 {
235   fflush (stdout);
236   ioctl (fileno (stdout), TIOCFLUSH, 0);
237   error ("Quit");
238 }
239
240 /* Control C comes here */
241
242 void
243 request_quit ()
244 {
245   quit_flag = 1;
246   if (immediate_quit)
247     quit ();
248 }
249
250 /* Print an error message and return to command level.
251    STRING is the error message, used as a fprintf string,
252    and ARG is passed as an argument to it.  */
253
254 void
255 error (string, arg1, arg2, arg3)
256      char *string;
257      int arg1, arg2, arg3;
258 {
259   fflush (stdout);
260   fprintf (stderr, string, arg1, arg2, arg3);
261   fprintf (stderr, "\n");
262   /************return_to_top_level ();************/ 
263 }
264
265 /* Print an error message and exit reporting failure.
266    This is for a error that we cannot continue from.
267    STRING and ARG are passed to fprintf.  */
268
269 void
270 fatal (string, arg)
271      char *string;
272      int arg;
273 {
274   fprintf (stderr, "gdb: ");
275   fprintf (stderr, string, arg);
276   fprintf (stderr, "\n");
277   exit (1);
278 }
279
280 /* Make a copy of the string at PTR with SIZE characters
281    (and add a null character at the end in the copy).
282    Uses malloc to get the space.  Returns the address of the copy.  */
283
284 char *
285 savestring (ptr, size)
286      char *ptr;
287      int size;
288 {
289   register char *p = (char *) xmalloc (size + 1);
290   bcopy (ptr, p, size);
291   p[size] = 0;
292   return p;
293 }
294
295 void
296 print_spaces (n, file)
297      register int n;
298      register FILE *file;
299 {
300   while (n-- > 0)
301     fputc (' ', file);
302 }
303
304 /* Ask user a y-or-n question and return 1 iff answer is yes.
305    Takes three args which are given to printf to print the question.
306    The first, a control string, should end in "? ".
307    It should not say how to answer, because we do that.  */
308
309 int
310 query (ctlstr, arg1, arg2)
311      char *ctlstr;
312 {
313   register int answer;
314
315   /* Automatically answer "yes" if input is not from a terminal.  */
316   /***********if (!input_from_terminal_p ())
317     return 1; *************************/ 
318
319   while (1)
320     {
321       printf (ctlstr, arg1, arg2);
322       printf ("(y or n) ");
323       fflush (stdout);
324       answer = fgetc (stdin);
325       clearerr (stdin);         /* in case of C-d */
326       if (answer != '\n')
327         while (fgetc (stdin) != '\n') clearerr (stdin);
328       if (answer >= 'a')
329         answer -= 040;
330       if (answer == 'Y')
331         return 1;
332       if (answer == 'N')
333         return 0;
334       printf ("Please answer y or n.\n");
335     }
336 }
337 \f
338 /* Parse a C escape sequence.  STRING_PTR points to a variable
339    containing a pointer to the string to parse.  That pointer
340    is updated past the characters we use.  The value of the
341    escape sequence is returned.
342
343    A negative value means the sequence \ newline was seen,
344    which is supposed to be equivalent to nothing at all.
345
346    If \ is followed by a null character, we return a negative
347    value and leave the string pointer pointing at the null character.
348
349    If \ is followed by 000, we return 0 and leave the string pointer
350    after the zeros.  A value of 0 does not mean end of string.  */
351
352 int
353 parse_escape (string_ptr)
354      char **string_ptr;
355 {
356   register int c = *(*string_ptr)++;
357   switch (c)
358     {
359     case 'a':
360       return '\a';
361     case 'b':
362       return '\b';
363     case 'e':
364       return 033;
365     case 'f':
366       return '\f';
367     case 'n':
368       return '\n';
369     case 'r':
370       return '\r';
371     case 't':
372       return '\t';
373     case 'v':
374       return '\v';
375     case '\n':
376       return -2;
377     case 0:
378       (*string_ptr)--;
379       return 0;
380     case '^':
381       c = *(*string_ptr)++;
382       if (c == '\\')
383         c = parse_escape (string_ptr);
384       if (c == '?')
385         return 0177;
386       return (c & 0200) | (c & 037);
387       
388     case '0':
389     case '1':
390     case '2':
391     case '3':
392     case '4':
393     case '5':
394     case '6':
395     case '7':
396       {
397         register int i = c - '0';
398         register int count = 0;
399         while (++count < 3)
400           {
401             if ((c = *(*string_ptr)++) >= '0' && c <= '7')
402               {
403                 i *= 8;
404                 i += c - '0';
405               }
406             else
407               {
408                 (*string_ptr)--;
409                 break;
410               }
411           }
412         return i;
413       }
414     default:
415       return c;
416     }
417 }
418 \f
419 void
420 printchar (ch, stream)
421      unsigned char ch;
422      FILE *stream;
423 {
424   register int c = ch;
425   if (c < 040 || c >= 0177)
426     {
427       if (c == '\n')
428         fprintf (stream, "\\n");
429       else if (c == '\b')
430         fprintf (stream, "\\b");
431       else if (c == '\t')
432         fprintf (stream, "\\t");
433       else if (c == '\f')
434         fprintf (stream, "\\f");
435       else if (c == '\r')
436         fprintf (stream, "\\r");
437       else if (c == 033)
438         fprintf (stream, "\\e");
439       else if (c == '\a')
440         fprintf (stream, "\\a");
441       else
442         fprintf (stream, "\\%03o", c);
443     }
444   else
445     {
446       if (c == '\\' || c == '"' || c == '\'')
447         fputc ('\\', stream);
448       fputc (c, stream);
449     }
450 }
451 SHAR_EOF
452 cat << \SHAR_EOF > remote_inflow.c
453 /* Low level interface to ptrace, for GDB when running under Unix.
454    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
455 */
456
457 #include "defs.h"
458 #include "param.h"
459 #include "wait.h"
460 #include "frame.h"
461 #include "inferior.h"
462 /***************************
463 #include "initialize.h"
464 ****************************/ 
465
466 #include <stdio.h>
467 #include <sys/param.h>
468 #include <sys/dir.h>
469 #include <sys/user.h>
470 #include <signal.h>
471 #include <sys/ioctl.h>
472 #include <sgtty.h>
473 #include <fcntl.h>
474
475 /***************Begin MY defs*********************/ 
476 int quit_flag = 0; 
477 char registers[REGISTER_BYTES]; 
478
479 /* Index within `registers' of the first byte of the space for
480    register N.  */
481
482
483 char buf2[MAX_REGISTER_RAW_SIZE];
484 /***************End MY defs*********************/ 
485
486 #ifdef NEW_SUN_PTRACE
487 #include <sys/ptrace.h>
488 #include <machine/reg.h>
489 #endif
490
491 extern char **environ; 
492 extern int errno;
493 extern int inferior_pid; 
494 void error(), quit(), perror_with_name();
495 int query(); 
496 void supply_register(), write_register(); 
497 CORE_ADDR read_register(); 
498
499 /* Nonzero if we are debugging an attached outside process
500    rather than an inferior.  */
501
502
503 /* Start an inferior process and returns its pid.
504    ALLARGS is a vector of program-name and args.
505    ENV is the environment vector to pass.  */
506
507 int
508 create_inferior (allargs, env)
509      char **allargs;
510      char **env;
511 {
512   int pid;
513   extern int sys_nerr;
514   extern char *sys_errlist[];
515   extern int errno;
516
517   /* exec is said to fail if the executable is open.  */
518   /****************close_exec_file ();*****************/ 
519
520   pid = vfork ();
521   if (pid < 0)
522     perror_with_name ("vfork");
523
524   if (pid == 0)
525     {
526       /* Run inferior in a separate process group.  */
527       setpgrp (getpid (), getpid ());
528
529 /* Not needed on Sun, at least, and loses there
530    because it clobbers the superior.  */
531 /*???      signal (SIGQUIT, SIG_DFL);
532       signal (SIGINT, SIG_DFL);  */
533
534           errno = 0; 
535       ptrace (0);
536
537       execle ("/bin/sh", "sh", "-c", allargs, 0, env);
538
539       fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
540                errno < sys_nerr ? sys_errlist[errno] : "unknown error");
541       fflush (stderr);
542       _exit (0177);
543     }
544   return pid;
545 }
546
547 /* Kill the inferior process.  Make us have no inferior.  */
548
549 kill_inferior ()
550 {
551   if (inferior_pid == 0)
552     return;
553   ptrace (8, inferior_pid, 0, 0);
554   wait (0);
555   /*************inferior_died ();****VK**************/ 
556 }
557
558 /* Resume execution of the inferior process.
559    If STEP is nonzero, single-step it.
560    If SIGNAL is nonzero, give it that signal.  */
561
562 unsigned char
563 resume (step, signal,status)
564      int step;
565      int signal;
566          char *status; 
567 {
568         int pid ; 
569         WAITTYPE w; 
570
571         errno = 0;
572     ptrace (step ? 9 : 7, inferior_pid, 1, signal);
573     if (errno)
574                 perror_with_name ("ptrace");
575         pid = wait(&w); 
576         if(pid != inferior_pid) 
577                 perror_with_name ("wait"); 
578
579         if(WIFEXITED(w))
580         {
581                 printf("\nchild exited with retcode = %x \n",WRETCODE(w)); 
582                 *status = 'E'; 
583                 return((unsigned char) WRETCODE(w));
584         } 
585         else if(!WIFSTOPPED(w))
586         {
587                 printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); 
588                 *status = 'T'; 
589                 return((unsigned char) WTERMSIG(w)); 
590         } 
591         else 
592         {
593                 printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); 
594                 *status = 'S'; 
595                 return((unsigned char) WSTOPSIG(w)); 
596         } 
597                  
598 }
599
600
601 #ifdef NEW_SUN_PTRACE
602
603 void
604 fetch_inferior_registers ()
605 {
606   struct regs inferior_registers;
607   struct fp_status inferior_fp_registers;
608   extern char registers[];
609
610       ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
611       if (errno)
612                 perror_with_name ("ptrace");
613           /**********debugging begin **********/ 
614           print_some_registers(&inferior_registers); 
615           /**********debugging end **********/ 
616       ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
617       if (errno)
618                 perror_with_name ("ptrace");
619
620       bcopy (&inferior_registers, registers, 16 * 4);
621       bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
622              sizeof inferior_fp_registers.fps_regs);
623       *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
624       *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
625       bcopy (&inferior_fp_registers.fps_control,
626              &registers[REGISTER_BYTE (FPC_REGNUM)],
627              sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
628 }
629
630 /* Store our register values back into the inferior.
631    If REGNO is -1, do this for all registers.
632    Otherwise, REGNO specifies which register (so we can save time).  */
633
634 store_inferior_registers (regno)
635      int regno;
636 {
637   struct regs inferior_registers;
638   struct fp_status inferior_fp_registers;
639   extern char registers[];
640
641       bcopy (registers, &inferior_registers, 16 * 4);
642       bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
643              sizeof inferior_fp_registers.fps_regs);
644       inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
645       inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
646       bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
647              &inferior_fp_registers.fps_control,
648              sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
649
650       ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
651       if (errno)
652                 perror_with_name ("ptrace");
653       ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
654       if (errno)
655                 perror_with_name ("ptrace");
656 }
657
658 #endif /* not NEW_SUN_PTRACE */
659
660
661 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
662    in the NEW_SUN_PTRACE case.
663    It ought to be straightforward.  But it appears that writing did
664    not write the data that I specified.  I cannot understand where
665    it got the data that it actually did write.  */
666
667 /* Copy LEN bytes from inferior's memory starting at MEMADDR
668    to debugger memory starting at MYADDR.  */
669
670 read_inferior_memory (memaddr, myaddr, len)
671      CORE_ADDR memaddr;
672      char *myaddr;
673      int len;
674 {
675   register int i;
676   /* Round starting address down to longword boundary.  */
677   register CORE_ADDR addr = memaddr & - sizeof (int);
678   /* Round ending address up; get number of longwords that makes.  */
679   register int count
680     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
681   /* Allocate buffer of that many longwords.  */
682   register int *buffer = (int *) alloca (count * sizeof (int));
683
684   /* Read all the longwords */
685   for (i = 0; i < count; i++, addr += sizeof (int))
686     {
687         buffer[i] = ptrace (1, inferior_pid, addr, 0);
688     }
689
690   /* Copy appropriate bytes out of the buffer.  */
691   bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
692 }
693
694 /* Copy LEN bytes of data from debugger memory at MYADDR
695    to inferior's memory at MEMADDR.
696    On failure (cannot write the inferior)
697    returns the value of errno.  */
698
699 int
700 write_inferior_memory (memaddr, myaddr, len)
701      CORE_ADDR memaddr;
702      char *myaddr;
703      int len;
704 {
705   register int i;
706   /* Round starting address down to longword boundary.  */
707   register CORE_ADDR addr = memaddr & - sizeof (int);
708   /* Round ending address up; get number of longwords that makes.  */
709   register int count
710     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
711   /* Allocate buffer of that many longwords.  */
712   register int *buffer = (int *) alloca (count * sizeof (int));
713   extern int errno;
714
715   /* Fill start and end extra bytes of buffer with existing memory data.  */
716
717     buffer[0] = ptrace (1, inferior_pid, addr, 0);
718
719   if (count > 1)
720     {
721         buffer[count - 1]
722           = ptrace (1, inferior_pid,
723                     addr + (count - 1) * sizeof (int), 0);
724     }
725
726   /* Copy data to be written over corresponding part of buffer */
727
728   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
729
730   /* Write the entire buffer.  */
731
732   for (i = 0; i < count; i++, addr += sizeof (int))
733     {
734       errno = 0;
735         ptrace (4, inferior_pid, addr, buffer[i]);
736       if (errno)
737         return errno;
738     }
739
740   return 0;
741 }
742 \f
743 void
744 try_writing_regs_command ()
745 {
746   register int i;
747   register int value;
748   extern int errno;
749
750   if (inferior_pid == 0)
751     error ("There is no inferior process now.");
752
753   fetch_inferior_registers(); 
754   for (i = 0;i<18 ; i ++)
755     {
756       QUIT;
757       errno = 0;
758       value = read_register(i); 
759       write_register ( i, value);
760       if (errno == 0)
761         {
762                 printf (" Succeeded with register %d; value 0x%x (%d).\n",
763                   i, value, value);
764         }
765       else 
766                 printf (" Failed with register %d.\n", i);
767     }
768 }
769
770 void
771 initialize ()
772 {
773
774   inferior_pid = 0;
775
776
777 }
778
779
780 /* Return the contents of register REGNO,
781    regarding it as an integer.  */
782
783 CORE_ADDR
784 read_register (regno)
785      int regno;
786 {
787   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
788   return *(int *) &registers[REGISTER_BYTE (regno)];
789 }
790
791 /* Store VALUE in the register number REGNO, regarded as an integer.  */
792
793 void
794 write_register (regno, val)
795      int regno, val;
796 {
797   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
798   *(int *) &registers[REGISTER_BYTE (regno)] = val;
799
800   if (have_inferior_p ())
801     store_inferior_registers (regno);
802 }
803
804
805 int
806 have_inferior_p ()
807 {
808   return inferior_pid != 0;
809 }
810
811 print_some_registers(regs)
812 int regs[];
813 {
814    register int i;
815    for (i = 0; i < 18; i++) {
816          printf("reg[%d] = %x\n", i, regs[i]);
817          }
818 }
819
820 SHAR_EOF
821 cat << \SHAR_EOF > remote_server.c
822 /* Main code for remote server for GDB, the GNU Debugger.
823    Copyright (C) 1989 Free Software Foundation, Inc.
824
825 This file is part of GDB.
826
827 This program is free software; you can redistribute it and/or modify
828 it under the terms of the GNU General Public License as published by
829 the Free Software Foundation; either version 2 of the License, or
830 (at your option) any later version.
831
832 This program is distributed in the hope that it will be useful,
833 but WITHOUT ANY WARRANTY; without even the implied warranty of
834 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
835 GNU General Public License for more details.
836
837 You should have received a copy of the GNU General Public License
838 along with this program; if not, write to the Free Software
839 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
840
841 #include "param.h"
842 #include <stdio.h>
843
844 void read_inferior_memory(), fetch_inferior_registers(); 
845 unsigned char resume(); 
846 void kill_inferior(); 
847 void initialize(), try_writing_regs_command();  
848 int create_inferior(), read_register(); 
849
850 extern char registers[]; 
851 int inferior_pid; 
852 extern char **environ; 
853
854 /* Descriptor for I/O to remote machine.  */
855 int remote_desc;
856 int kiodebug = 0;
857 int remote_debugging; 
858
859 void remote_send ();
860 void putpkt ();
861 void getpkt ();
862 void remote_open(); 
863 void write_ok(); 
864 void write_enn(); 
865 void convert_ascii_to_int(); 
866 void convert_int_to_ascii(); 
867 void prepare_resume_reply(); 
868 void decode_m_packet(); 
869 void decode_M_packet(); 
870
871
872 main(argc,argv)
873 int argc; char *argv[]; 
874 {
875     char ch,status, own_buf[2000], mem_buf[2000]; 
876         int i=0;  
877         unsigned char signal;  
878         unsigned int mem_addr, len; 
879
880         initialize(); 
881     printf("\nwill open serial link\n"); 
882     remote_open("/dev/ttya",0); 
883
884         if(argc < 2) 
885         { 
886                 printf("Enter name of program to be run with command line args\n"); 
887                 gets(own_buf); 
888                 inferior_pid = create_inferior(own_buf,environ); 
889                 printf("\nProcess %s created; pid = %d\n",own_buf,inferior_pid);
890         } 
891         else 
892         { 
893                 inferior_pid = create_inferior(argv[1],environ); 
894                 printf("\nProcess %s created; pid = %d\n",argv[1],inferior_pid);
895         } 
896
897     do {  
898         getpkt(own_buf); 
899         printf("\nPacket received is>:%s\n",own_buf); 
900                 i = 0; 
901                 ch = own_buf[i++]; 
902             switch (ch) { 
903                         case 'h':       /**********This is only for tweaking the gdb+ program *******/ 
904                                                 signal = resume(1,0,&status);
905                                                 prepare_resume_reply(own_buf,status,signal); 
906                                                 break; 
907                                                 /*************end tweak*************************************/ 
908
909                         case 'g':       fetch_inferior_registers();             
910                                                 convert_int_to_ascii(registers,own_buf,REGISTER_BYTES); 
911                                                 break; 
912                         case 'G':       convert_ascii_to_int(&own_buf[1],registers,REGISTER_BYTES);
913                                                 if(store_inferior_registers(-1)==0)  
914                                                         write_ok(own_buf); 
915                                                 else  
916                                                         write_enn(own_buf); 
917                                                 break; 
918                         case 'm':       decode_m_packet(&own_buf[1],&mem_addr,&len); 
919                                                 read_inferior_memory(mem_addr,mem_buf,len);
920                                                 convert_int_to_ascii(mem_buf,own_buf,len); 
921                                                 break; 
922                         case 'M':       decode_M_packet(&own_buf[1],&mem_addr,&len,mem_buf); 
923                                                 if(write_inferior_memory(mem_addr,mem_buf,len)==0)  
924                                                         write_ok(own_buf); 
925                                                 else 
926                                                         write_enn(own_buf); 
927                                                 break; 
928                         case 'c':       signal = resume(0,0,&status);
929                                                 printf("\nSignal received is >: %0x \n",signal); 
930                                                 prepare_resume_reply(own_buf,status,signal); 
931                                                 break; 
932                         case 's':       signal = resume(1,0,&status);
933                                                 prepare_resume_reply(own_buf,status,signal); 
934                                                 break; 
935                         case 'k':       kill_inferior();
936                                                 sprintf(own_buf,"q"); 
937                                         putpkt(own_buf); 
938                                                 printf("\nObtained kill request...terminating\n"); 
939                                         close(remote_desc); 
940                                                 exit(0); 
941                         case 't':       try_writing_regs_command();
942                                                 own_buf[0] = '\0'; 
943                                                 break; 
944                         default :       printf("\nUnknown option chosen by master\n"); 
945                                                 write_enn(own_buf); 
946                                                 break; 
947                   } 
948
949         putpkt(own_buf); 
950      }  while(1) ; 
951
952     close(remote_desc); 
953     /** now get out of here**/ 
954     printf("\nFinished reading data from serial link - Bye!\n"); 
955     exit(0);
956
957 }
958
959 SHAR_EOF
960 cat << \SHAR_EOF > remote_utils.c
961 /* Remote utility routines for the remote server for GDB, the GNU debugger.
962    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
963
964 This file is part of GDB.
965
966 This program is free software; you can redistribute it and/or modify
967 it under the terms of the GNU General Public License as published by
968 the Free Software Foundation; either version 2 of the License, or
969 (at your option) any later version.
970
971 This program is distributed in the hope that it will be useful,
972 but WITHOUT ANY WARRANTY; without even the implied warranty of
973 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
974 GNU General Public License for more details.
975
976 You should have received a copy of the GNU General Public License
977 along with this program; if not, write to the Free Software
978 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
979
980 #include "param.h"
981 #include <stdio.h>
982 #include <signal.h>
983 #include <sys/wait.h>
984 #include <sys/ioctl.h>
985 #include <a.out.h>
986 #include <sys/file.h>
987 #include <sgtty.h> 
988
989 extern int remote_desc; 
990 extern int remote_debugging; 
991 extern int kiodebug; 
992
993 void remote_open(); 
994 void remote_send(); 
995 void putpkt(); 
996 void getpkt(); 
997
998 void write_ok(); 
999 void write_enn(); 
1000 void convert_ascii_to_int(); 
1001 void convert_int_to_ascii(); 
1002 void prepare_resume_reply(); 
1003
1004 /* Open a connection to a remote debugger.
1005    NAME is the filename used for communication.  */
1006
1007 void
1008 remote_open (name, from_tty)
1009      char *name;
1010      int from_tty;
1011 {
1012   struct sgttyb sg;
1013
1014   remote_debugging = 0;
1015
1016   remote_desc = open (name, O_RDWR);
1017   if (remote_desc < 0)
1018     printf("\ncould not open remote device\n"); 
1019
1020   ioctl (remote_desc, TIOCGETP, &sg);
1021   sg.sg_flags = RAW;
1022   ioctl (remote_desc, TIOCSETP, &sg);
1023
1024   if (from_tty)
1025     printf ("Remote debugging using %s\n", name);
1026   remote_debugging = 1;
1027 }
1028
1029 /* Convert hex digit A to a number.  */
1030
1031 static int
1032 fromhex (a)
1033      int a;
1034 {
1035   if (a >= '0' && a <= '9')
1036     return a - '0';
1037   else if (a >= 'a' && a <= 'f')
1038     return a - 'a' + 10;
1039   else
1040     perror ("Reply contains invalid hex digit");
1041 }
1042
1043 /* Convert number NIB to a hex digit.  */
1044
1045 static int
1046 tohex (nib)
1047      int nib;
1048 {
1049   if (nib < 10)
1050     return '0'+nib;
1051   else
1052     return 'a'+nib-10;
1053 }
1054
1055 /* Send the command in BUF to the remote machine,
1056    and read the reply into BUF.
1057    Report an error if we get an error reply.  */
1058
1059 void
1060 remote_send (buf)
1061      char *buf;
1062 {
1063   putpkt (buf);
1064   getpkt (buf);
1065
1066   if (buf[0] == 'E')
1067     perror ("Remote failure reply: %s", buf);
1068 }
1069
1070 /* Send a packet to the remote machine, with error checking.
1071    The data of the packet is in BUF.  */
1072
1073 void
1074 putpkt (buf)
1075      char *buf;
1076 {
1077   int i;
1078   unsigned char csum = 0;
1079   char buf2[500];
1080   char buf3[1];
1081   int cnt = strlen (buf);
1082   char *p;
1083
1084   if (kiodebug)
1085     fprintf (stderr, "Sending packet: %s\n", buf);
1086
1087   /* Copy the packet into buffer BUF2, encapsulating it
1088      and giving it a checksum.  */
1089
1090   p = buf2;
1091   *p++ = '$';
1092
1093   for (i = 0; i < cnt; i++)
1094     {
1095       csum += buf[i];
1096       *p++ = buf[i];
1097     }
1098   *p++ = '#';
1099   *p++ = tohex ((csum >> 4) & 0xf);
1100   *p++ = tohex (csum & 0xf);
1101
1102   /* Send it over and over until we get a positive ack.  */
1103
1104   do {
1105     write (remote_desc, buf2, p - buf2);
1106     read (remote_desc, buf3, 1);
1107   } while (buf3[0] != '+');
1108 }
1109
1110 static int
1111 readchar ()
1112 {
1113   char buf[1];
1114   while (read (remote_desc, buf, 1) != 1) ;
1115   return buf[0] & 0x7f;
1116 }
1117
1118 /* Read a packet from the remote machine, with error checking,
1119    and store it in BUF.  */
1120
1121 void
1122 getpkt (buf)
1123      char *buf;
1124 {
1125   char *bp;
1126   unsigned char csum, c, c1, c2;
1127   extern kiodebug;
1128
1129   while (1)
1130     {
1131           csum = 0; 
1132       while ((c = readchar()) != '$');
1133
1134       bp = buf;
1135       while (1)
1136         {
1137           c = readchar ();
1138           if (c == '#')
1139             break;
1140           *bp++ = c;
1141           csum += c;
1142         }
1143       *bp = 0;
1144
1145       c1 = fromhex (readchar ());
1146       c2 = fromhex (readchar ());
1147       if (csum == (c1 << 4) + c2)
1148             break;
1149
1150       printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
1151               (c1 << 4) + c2, csum, buf);
1152       write (remote_desc, "-", 1);
1153     }
1154
1155   write (remote_desc, "+", 1);
1156
1157   if (kiodebug)
1158     fprintf (stderr,"Packet received :%s\n", buf);
1159 }
1160
1161
1162 void 
1163 write_ok(buf)
1164         char *buf; 
1165 {
1166         buf[0] = 'O';
1167         buf[1] = 'k';
1168         buf[2] = '\0';
1169 }
1170
1171 void 
1172 write_enn(buf)
1173         char *buf; 
1174 {
1175         buf[0] = 'E';
1176         buf[1] = 'N';
1177         buf[2] = 'N';
1178         buf[3] = '\0';
1179 }
1180
1181 void
1182 convert_int_to_ascii(from,to,n)
1183 char *from, *to; int n; 
1184 {
1185         int nib ; 
1186         char ch; 
1187         while( n-- )
1188         {
1189                 ch = *from++;           
1190                 nib = ((ch & 0xf0) >> 4)& 0x0f; 
1191                 *to++ = tohex(nib); 
1192                 nib = ch & 0x0f; 
1193                 *to++ = tohex(nib); 
1194         } 
1195         *to++ = 0; 
1196 }
1197
1198
1199 void
1200 convert_ascii_to_int(from,to,n)
1201 char *from, *to; int n;  
1202 {
1203         int nib1,nib2 ; 
1204         while( n-- )
1205         {
1206                 nib1 = fromhex(*from++); 
1207                 nib2 = fromhex(*from++); 
1208                 *to++ = (((nib1 & 0x0f)<< 4)& 0xf0) | (nib2 & 0x0f); 
1209         } 
1210 }
1211
1212 void
1213 prepare_resume_reply(buf,status,signal)
1214 char *buf ,status; 
1215 unsigned char signal; 
1216 {
1217         int nib; 
1218         char ch; 
1219
1220         *buf++ = 'S';  
1221         *buf++ = status;  
1222         nib = ((signal & 0xf0) >> 4) ; 
1223         *buf++ = tohex(nib); 
1224         nib = signal & 0x0f; 
1225         *buf++ = tohex(nib); 
1226         *buf++ = 0; 
1227 }
1228
1229 void 
1230 decode_m_packet(from,mem_addr_ptr,len_ptr)
1231 char *from;
1232 unsigned int *mem_addr_ptr, *len_ptr; 
1233 {
1234         int i = 0, j = 0 ; 
1235         char ch; 
1236         *mem_addr_ptr = *len_ptr = 0; 
1237         /************debugging begin************/ 
1238         printf("\nIn decode_m_packet"); 
1239         /************debugging end************/ 
1240
1241         while((ch = from[i++]) != ',') 
1242         { 
1243                 *mem_addr_ptr = *mem_addr_ptr << 4; 
1244                 *mem_addr_ptr |= fromhex(ch) & 0x0f; 
1245         } 
1246         /************debugging begin************/ 
1247         printf("\nFinished mem_addr part"); 
1248         /************debugging end************/ 
1249
1250         for(j=0; j < 4; j++) 
1251         { 
1252                 if((ch = from[i++]) == 0)  
1253                         break; 
1254                 *len_ptr = *len_ptr << 4; 
1255                 *len_ptr |= fromhex(ch) & 0x0f; 
1256         } 
1257         /************debugging begin************/ 
1258         printf("\nFinished len_ptr part"); 
1259         /************debugging end************/ 
1260 }
1261
1262 void 
1263 decode_M_packet(from,mem_addr_ptr,len_ptr,to)
1264 char *from, *to;
1265 unsigned int *mem_addr_ptr, *len_ptr; 
1266 {
1267         int i = 0, j = 0 ; 
1268         char ch; 
1269         *mem_addr_ptr = *len_ptr = 0; 
1270         /************debugging begin************/ 
1271         printf("\nIn decode_M_packet"); 
1272         /************debugging end************/ 
1273
1274         while((ch = from[i++]) != ',') 
1275         { 
1276                 *mem_addr_ptr = *mem_addr_ptr << 4; 
1277                 *mem_addr_ptr |= fromhex(ch) & 0x0f; 
1278         } 
1279         /************debugging begin************/ 
1280         printf("\nFinished mem_addr part: memaddr = %x",*mem_addr_ptr); 
1281         /************debugging end************/ 
1282
1283         while((ch = from[i++]) != ':') 
1284         { 
1285                 *len_ptr = *len_ptr << 4; 
1286                 *len_ptr |= fromhex(ch) & 0x0f; 
1287         } 
1288         /************debugging begin************/ 
1289         printf("\nFinished len_ptr part: len = %d",*len_ptr); 
1290         /************debugging end************/ 
1291
1292         convert_ascii_to_int(&from[i++],to,*len_ptr); 
1293
1294         /************debugging begin************/ 
1295         printf("\nmembuf : %x",*(int *)to); 
1296         /************debugging end************/ 
1297 }
1298
1299 SHAR_EOF
1300 #       End of shell archive
1301 exit 0
This page took 0.0971379999999999 seconds and 4 git commands to generate.