* stabs.texinfo: Document the format for C++ nested types.
[deliverable/binutils-gdb.git] / gdb / remote-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 # GDB 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 1, or (at your option)
21 # any later version.
22 #
23 # GDB 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 GDB; see the file COPYING. If not, write to
30 # the Free Software Foundation, 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 GDB 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 1, or (at your option)
52 any later version.
53
54 GDB 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 GDB; see the file COPYING. If not, write to
61 the Free Software Foundation, 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 char *
296 concat (s1, s2, s3)
297 char *s1, *s2, *s3;
298 {
299 register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
300 register char *val = (char *) xmalloc (len);
301 strcpy (val, s1);
302 strcat (val, s2);
303 strcat (val, s3);
304 return val;
305 }
306
307 void
308 print_spaces (n, file)
309 register int n;
310 register FILE *file;
311 {
312 while (n-- > 0)
313 fputc (' ', file);
314 }
315
316 /* Ask user a y-or-n question and return 1 iff answer is yes.
317 Takes three args which are given to printf to print the question.
318 The first, a control string, should end in "? ".
319 It should not say how to answer, because we do that. */
320
321 int
322 query (ctlstr, arg1, arg2)
323 char *ctlstr;
324 {
325 register int answer;
326
327 /* Automatically answer "yes" if input is not from a terminal. */
328 /***********if (!input_from_terminal_p ())
329 return 1; *************************/
330
331 while (1)
332 {
333 printf (ctlstr, arg1, arg2);
334 printf ("(y or n) ");
335 fflush (stdout);
336 answer = fgetc (stdin);
337 clearerr (stdin); /* in case of C-d */
338 if (answer != '\n')
339 while (fgetc (stdin) != '\n') clearerr (stdin);
340 if (answer >= 'a')
341 answer -= 040;
342 if (answer == 'Y')
343 return 1;
344 if (answer == 'N')
345 return 0;
346 printf ("Please answer y or n.\n");
347 }
348 }
349 \f
350 /* Parse a C escape sequence. STRING_PTR points to a variable
351 containing a pointer to the string to parse. That pointer
352 is updated past the characters we use. The value of the
353 escape sequence is returned.
354
355 A negative value means the sequence \ newline was seen,
356 which is supposed to be equivalent to nothing at all.
357
358 If \ is followed by a null character, we return a negative
359 value and leave the string pointer pointing at the null character.
360
361 If \ is followed by 000, we return 0 and leave the string pointer
362 after the zeros. A value of 0 does not mean end of string. */
363
364 int
365 parse_escape (string_ptr)
366 char **string_ptr;
367 {
368 register int c = *(*string_ptr)++;
369 switch (c)
370 {
371 case 'a':
372 return '\a';
373 case 'b':
374 return '\b';
375 case 'e':
376 return 033;
377 case 'f':
378 return '\f';
379 case 'n':
380 return '\n';
381 case 'r':
382 return '\r';
383 case 't':
384 return '\t';
385 case 'v':
386 return '\v';
387 case '\n':
388 return -2;
389 case 0:
390 (*string_ptr)--;
391 return 0;
392 case '^':
393 c = *(*string_ptr)++;
394 if (c == '\\')
395 c = parse_escape (string_ptr);
396 if (c == '?')
397 return 0177;
398 return (c & 0200) | (c & 037);
399
400 case '0':
401 case '1':
402 case '2':
403 case '3':
404 case '4':
405 case '5':
406 case '6':
407 case '7':
408 {
409 register int i = c - '0';
410 register int count = 0;
411 while (++count < 3)
412 {
413 if ((c = *(*string_ptr)++) >= '0' && c <= '7')
414 {
415 i *= 8;
416 i += c - '0';
417 }
418 else
419 {
420 (*string_ptr)--;
421 break;
422 }
423 }
424 return i;
425 }
426 default:
427 return c;
428 }
429 }
430 \f
431 void
432 printchar (ch, stream)
433 unsigned char ch;
434 FILE *stream;
435 {
436 register int c = ch;
437 if (c < 040 || c >= 0177)
438 {
439 if (c == '\n')
440 fprintf (stream, "\\n");
441 else if (c == '\b')
442 fprintf (stream, "\\b");
443 else if (c == '\t')
444 fprintf (stream, "\\t");
445 else if (c == '\f')
446 fprintf (stream, "\\f");
447 else if (c == '\r')
448 fprintf (stream, "\\r");
449 else if (c == 033)
450 fprintf (stream, "\\e");
451 else if (c == '\a')
452 fprintf (stream, "\\a");
453 else
454 fprintf (stream, "\\%03o", c);
455 }
456 else
457 {
458 if (c == '\\' || c == '"' || c == '\'')
459 fputc ('\\', stream);
460 fputc (c, stream);
461 }
462 }
463 SHAR_EOF
464 cat << \SHAR_EOF > remote_inflow.c
465 /* Low level interface to ptrace, for GDB when running under Unix.
466 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
467 */
468
469 #include "defs.h"
470 #include "param.h"
471 #include "wait.h"
472 #include "frame.h"
473 #include "inferior.h"
474 /***************************
475 #include "initialize.h"
476 ****************************/
477
478 #include <stdio.h>
479 #include <sys/param.h>
480 #include <sys/dir.h>
481 #include <sys/user.h>
482 #include <signal.h>
483 #include <sys/ioctl.h>
484 #include <sgtty.h>
485 #include <fcntl.h>
486
487 /***************Begin MY defs*********************/
488 int quit_flag = 0;
489 char registers[REGISTER_BYTES];
490
491 /* Index within `registers' of the first byte of the space for
492 register N. */
493
494
495 char buf2[MAX_REGISTER_RAW_SIZE];
496 /***************End MY defs*********************/
497
498 #ifdef NEW_SUN_PTRACE
499 #include <sys/ptrace.h>
500 #include <machine/reg.h>
501 #endif
502
503 extern char **environ;
504 extern int errno;
505 extern int inferior_pid;
506 void error(), quit(), perror_with_name();
507 int query();
508 void supply_register(), write_register();
509 CORE_ADDR read_register();
510
511 /* Nonzero if we are debugging an attached outside process
512 rather than an inferior. */
513
514
515 /* Start an inferior process and returns its pid.
516 ALLARGS is a vector of program-name and args.
517 ENV is the environment vector to pass. */
518
519 int
520 create_inferior (allargs, env)
521 char **allargs;
522 char **env;
523 {
524 int pid;
525 extern int sys_nerr;
526 extern char *sys_errlist[];
527 extern int errno;
528
529 /* exec is said to fail if the executable is open. */
530 /****************close_exec_file ();*****************/
531
532 pid = vfork ();
533 if (pid < 0)
534 perror_with_name ("vfork");
535
536 if (pid == 0)
537 {
538 /* Run inferior in a separate process group. */
539 setpgrp (getpid (), getpid ());
540
541 /* Not needed on Sun, at least, and loses there
542 because it clobbers the superior. */
543 /*??? signal (SIGQUIT, SIG_DFL);
544 signal (SIGINT, SIG_DFL); */
545
546 errno = 0;
547 ptrace (0);
548
549 execle ("/bin/sh", "sh", "-c", allargs, 0, env);
550
551 fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
552 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
553 fflush (stderr);
554 _exit (0177);
555 }
556 return pid;
557 }
558
559 /* Kill the inferior process. Make us have no inferior. */
560
561 kill_inferior ()
562 {
563 if (inferior_pid == 0)
564 return;
565 ptrace (8, inferior_pid, 0, 0);
566 wait (0);
567 /*************inferior_died ();****VK**************/
568 }
569
570 /* Resume execution of the inferior process.
571 If STEP is nonzero, single-step it.
572 If SIGNAL is nonzero, give it that signal. */
573
574 unsigned char
575 resume (step, signal,status)
576 int step;
577 int signal;
578 char *status;
579 {
580 int pid ;
581 WAITTYPE w;
582
583 errno = 0;
584 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
585 if (errno)
586 perror_with_name ("ptrace");
587 pid = wait(&w);
588 if(pid != inferior_pid)
589 perror_with_name ("wait");
590
591 if(WIFEXITED(w))
592 {
593 printf("\nchild exited with retcode = %x \n",WRETCODE(w));
594 *status = 'E';
595 return((unsigned char) WRETCODE(w));
596 }
597 else if(!WIFSTOPPED(w))
598 {
599 printf("\nchild did terminated with signal = %x \n",WTERMSIG(w));
600 *status = 'T';
601 return((unsigned char) WTERMSIG(w));
602 }
603 else
604 {
605 printf("\nchild stopped with signal = %x \n",WSTOPSIG(w));
606 *status = 'S';
607 return((unsigned char) WSTOPSIG(w));
608 }
609
610 }
611
612
613 #ifdef NEW_SUN_PTRACE
614
615 void
616 fetch_inferior_registers ()
617 {
618 struct regs inferior_registers;
619 struct fp_status inferior_fp_registers;
620 extern char registers[];
621
622 ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
623 if (errno)
624 perror_with_name ("ptrace");
625 /**********debugging begin **********/
626 print_some_registers(&inferior_registers);
627 /**********debugging end **********/
628 ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
629 if (errno)
630 perror_with_name ("ptrace");
631
632 bcopy (&inferior_registers, registers, 16 * 4);
633 bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
634 sizeof inferior_fp_registers.fps_regs);
635 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
636 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
637 bcopy (&inferior_fp_registers.fps_control,
638 &registers[REGISTER_BYTE (FPC_REGNUM)],
639 sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
640 }
641
642 /* Store our register values back into the inferior.
643 If REGNO is -1, do this for all registers.
644 Otherwise, REGNO specifies which register (so we can save time). */
645
646 store_inferior_registers (regno)
647 int regno;
648 {
649 struct regs inferior_registers;
650 struct fp_status inferior_fp_registers;
651 extern char registers[];
652
653 bcopy (registers, &inferior_registers, 16 * 4);
654 bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
655 sizeof inferior_fp_registers.fps_regs);
656 inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
657 inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
658 bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
659 &inferior_fp_registers.fps_control,
660 sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
661
662 ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
663 if (errno)
664 perror_with_name ("ptrace");
665 ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
666 if (errno)
667 perror_with_name ("ptrace");
668 }
669
670 #endif /* not NEW_SUN_PTRACE */
671
672
673 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
674 in the NEW_SUN_PTRACE case.
675 It ought to be straightforward. But it appears that writing did
676 not write the data that I specified. I cannot understand where
677 it got the data that it actually did write. */
678
679 /* Copy LEN bytes from inferior's memory starting at MEMADDR
680 to debugger memory starting at MYADDR. */
681
682 read_inferior_memory (memaddr, myaddr, len)
683 CORE_ADDR memaddr;
684 char *myaddr;
685 int len;
686 {
687 register int i;
688 /* Round starting address down to longword boundary. */
689 register CORE_ADDR addr = memaddr & - sizeof (int);
690 /* Round ending address up; get number of longwords that makes. */
691 register int count
692 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
693 /* Allocate buffer of that many longwords. */
694 register int *buffer = (int *) alloca (count * sizeof (int));
695
696 /* Read all the longwords */
697 for (i = 0; i < count; i++, addr += sizeof (int))
698 {
699 buffer[i] = ptrace (1, inferior_pid, addr, 0);
700 }
701
702 /* Copy appropriate bytes out of the buffer. */
703 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
704 }
705
706 /* Copy LEN bytes of data from debugger memory at MYADDR
707 to inferior's memory at MEMADDR.
708 On failure (cannot write the inferior)
709 returns the value of errno. */
710
711 int
712 write_inferior_memory (memaddr, myaddr, len)
713 CORE_ADDR memaddr;
714 char *myaddr;
715 int len;
716 {
717 register int i;
718 /* Round starting address down to longword boundary. */
719 register CORE_ADDR addr = memaddr & - sizeof (int);
720 /* Round ending address up; get number of longwords that makes. */
721 register int count
722 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
723 /* Allocate buffer of that many longwords. */
724 register int *buffer = (int *) alloca (count * sizeof (int));
725 extern int errno;
726
727 /* Fill start and end extra bytes of buffer with existing memory data. */
728
729 buffer[0] = ptrace (1, inferior_pid, addr, 0);
730
731 if (count > 1)
732 {
733 buffer[count - 1]
734 = ptrace (1, inferior_pid,
735 addr + (count - 1) * sizeof (int), 0);
736 }
737
738 /* Copy data to be written over corresponding part of buffer */
739
740 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
741
742 /* Write the entire buffer. */
743
744 for (i = 0; i < count; i++, addr += sizeof (int))
745 {
746 errno = 0;
747 ptrace (4, inferior_pid, addr, buffer[i]);
748 if (errno)
749 return errno;
750 }
751
752 return 0;
753 }
754 \f
755 void
756 try_writing_regs_command ()
757 {
758 register int i;
759 register int value;
760 extern int errno;
761
762 if (inferior_pid == 0)
763 error ("There is no inferior process now.");
764
765 fetch_inferior_registers();
766 for (i = 0;i<18 ; i ++)
767 {
768 QUIT;
769 errno = 0;
770 value = read_register(i);
771 write_register ( i, value);
772 if (errno == 0)
773 {
774 printf (" Succeeded with register %d; value 0x%x (%d).\n",
775 i, value, value);
776 }
777 else
778 printf (" Failed with register %d.\n", i);
779 }
780 }
781
782 void
783 initialize ()
784 {
785
786 inferior_pid = 0;
787
788
789 }
790
791
792 /* Return the contents of register REGNO,
793 regarding it as an integer. */
794
795 CORE_ADDR
796 read_register (regno)
797 int regno;
798 {
799 /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
800 return *(int *) &registers[REGISTER_BYTE (regno)];
801 }
802
803 /* Store VALUE in the register number REGNO, regarded as an integer. */
804
805 void
806 write_register (regno, val)
807 int regno, val;
808 {
809 /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
810 *(int *) &registers[REGISTER_BYTE (regno)] = val;
811
812 if (have_inferior_p ())
813 store_inferior_registers (regno);
814 }
815
816
817 int
818 have_inferior_p ()
819 {
820 return inferior_pid != 0;
821 }
822
823 print_some_registers(regs)
824 int regs[];
825 {
826 register int i;
827 for (i = 0; i < 18; i++) {
828 printf("reg[%d] = %x\n", i, regs[i]);
829 }
830 }
831
832 SHAR_EOF
833 cat << \SHAR_EOF > remote_server.c
834 /* Main code for remote server for GDB, the GNU Debugger.
835 Copyright (C) 1989 Free Software Foundation, Inc.
836
837 This file is part of GDB.
838
839 GDB is free software; you can redistribute it and/or modify
840 it under the terms of the GNU General Public License as published by
841 the Free Software Foundation; either version 1, or (at your option)
842 any later version.
843
844 GDB is distributed in the hope that it will be useful,
845 but WITHOUT ANY WARRANTY; without even the implied warranty of
846 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
847 GNU General Public License for more details.
848
849 You should have received a copy of the GNU General Public License
850 along with GDB; see the file COPYING. If not, write to
851 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
852
853 #include "param.h"
854 #include <stdio.h>
855
856 void read_inferior_memory(), fetch_inferior_registers();
857 unsigned char resume();
858 void kill_inferior();
859 void initialize(), try_writing_regs_command();
860 int create_inferior(), read_register();
861
862 extern char registers[];
863 int inferior_pid;
864 extern char **environ;
865
866 /* Descriptor for I/O to remote machine. */
867 int remote_desc;
868 int kiodebug = 0;
869 int remote_debugging;
870
871 void remote_send ();
872 void putpkt ();
873 void getpkt ();
874 void remote_open();
875 void write_ok();
876 void write_enn();
877 void convert_ascii_to_int();
878 void convert_int_to_ascii();
879 void prepare_resume_reply();
880 void decode_m_packet();
881 void decode_M_packet();
882
883
884 main(argc,argv)
885 int argc; char *argv[];
886 {
887 char ch,status, own_buf[2000], mem_buf[2000];
888 int i=0;
889 unsigned char signal;
890 unsigned int mem_addr, len;
891
892 initialize();
893 printf("\nwill open serial link\n");
894 remote_open("/dev/ttya",0);
895
896 if(argc < 2)
897 {
898 printf("Enter name of program to be run with command line args\n");
899 gets(own_buf);
900 inferior_pid = create_inferior(own_buf,environ);
901 printf("\nProcess %s created; pid = %d\n",own_buf,inferior_pid);
902 }
903 else
904 {
905 inferior_pid = create_inferior(argv[1],environ);
906 printf("\nProcess %s created; pid = %d\n",argv[1],inferior_pid);
907 }
908
909 do {
910 getpkt(own_buf);
911 printf("\nPacket received is>:%s\n",own_buf);
912 i = 0;
913 ch = own_buf[i++];
914 switch (ch) {
915 case 'h': /**********This is only for tweaking the gdb+ program *******/
916 signal = resume(1,0,&status);
917 prepare_resume_reply(own_buf,status,signal);
918 break;
919 /*************end tweak*************************************/
920
921 case 'g': fetch_inferior_registers();
922 convert_int_to_ascii(registers,own_buf,REGISTER_BYTES);
923 break;
924 case 'G': convert_ascii_to_int(&own_buf[1],registers,REGISTER_BYTES);
925 if(store_inferior_registers(-1)==0)
926 write_ok(own_buf);
927 else
928 write_enn(own_buf);
929 break;
930 case 'm': decode_m_packet(&own_buf[1],&mem_addr,&len);
931 read_inferior_memory(mem_addr,mem_buf,len);
932 convert_int_to_ascii(mem_buf,own_buf,len);
933 break;
934 case 'M': decode_M_packet(&own_buf[1],&mem_addr,&len,mem_buf);
935 if(write_inferior_memory(mem_addr,mem_buf,len)==0)
936 write_ok(own_buf);
937 else
938 write_enn(own_buf);
939 break;
940 case 'c': signal = resume(0,0,&status);
941 printf("\nSignal received is >: %0x \n",signal);
942 prepare_resume_reply(own_buf,status,signal);
943 break;
944 case 's': signal = resume(1,0,&status);
945 prepare_resume_reply(own_buf,status,signal);
946 break;
947 case 'k': kill_inferior();
948 sprintf(own_buf,"q");
949 putpkt(own_buf);
950 printf("\nObtained kill request...terminating\n");
951 close(remote_desc);
952 exit(0);
953 case 't': try_writing_regs_command();
954 own_buf[0] = '\0';
955 break;
956 default : printf("\nUnknown option chosen by master\n");
957 write_enn(own_buf);
958 break;
959 }
960
961 putpkt(own_buf);
962 } while(1) ;
963
964 close(remote_desc);
965 /** now get out of here**/
966 printf("\nFinished reading data from serial link - Bye!\n");
967 exit(0);
968
969 }
970
971 SHAR_EOF
972 cat << \SHAR_EOF > remote_utils.c
973 /* Remote utility routines for the remote server for GDB, the GNU debugger.
974 Copyright (C) 1986, 1989 Free Software Foundation, Inc.
975
976 This file is part of GDB.
977
978 GDB is free software; you can redistribute it and/or modify
979 it under the terms of the GNU General Public License as published by
980 the Free Software Foundation; either version 1, or (at your option)
981 any later version.
982
983 GDB is distributed in the hope that it will be useful,
984 but WITHOUT ANY WARRANTY; without even the implied warranty of
985 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
986 GNU General Public License for more details.
987
988 You should have received a copy of the GNU General Public License
989 along with GDB; see the file COPYING. If not, write to
990 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
991
992 #include "param.h"
993 #include <stdio.h>
994 #include <signal.h>
995 #include <sys/wait.h>
996 #include <sys/ioctl.h>
997 #include <a.out.h>
998 #include <sys/file.h>
999 #include <sgtty.h>
1000
1001 extern int remote_desc;
1002 extern int remote_debugging;
1003 extern int kiodebug;
1004
1005 void remote_open();
1006 void remote_send();
1007 void putpkt();
1008 void getpkt();
1009
1010 void write_ok();
1011 void write_enn();
1012 void convert_ascii_to_int();
1013 void convert_int_to_ascii();
1014 void prepare_resume_reply();
1015
1016 /* Open a connection to a remote debugger.
1017 NAME is the filename used for communication. */
1018
1019 void
1020 remote_open (name, from_tty)
1021 char *name;
1022 int from_tty;
1023 {
1024 struct sgttyb sg;
1025
1026 remote_debugging = 0;
1027
1028 remote_desc = open (name, O_RDWR);
1029 if (remote_desc < 0)
1030 printf("\ncould not open remote device\n");
1031
1032 ioctl (remote_desc, TIOCGETP, &sg);
1033 sg.sg_flags = RAW;
1034 ioctl (remote_desc, TIOCSETP, &sg);
1035
1036 if (from_tty)
1037 printf ("Remote debugging using %s\n", name);
1038 remote_debugging = 1;
1039 }
1040
1041 /* Convert hex digit A to a number. */
1042
1043 static int
1044 fromhex (a)
1045 int a;
1046 {
1047 if (a >= '0' && a <= '9')
1048 return a - '0';
1049 else if (a >= 'a' && a <= 'f')
1050 return a - 'a' + 10;
1051 else
1052 perror ("Reply contains invalid hex digit");
1053 }
1054
1055 /* Convert number NIB to a hex digit. */
1056
1057 static int
1058 tohex (nib)
1059 int nib;
1060 {
1061 if (nib < 10)
1062 return '0'+nib;
1063 else
1064 return 'a'+nib-10;
1065 }
1066
1067 /* Send the command in BUF to the remote machine,
1068 and read the reply into BUF.
1069 Report an error if we get an error reply. */
1070
1071 void
1072 remote_send (buf)
1073 char *buf;
1074 {
1075 putpkt (buf);
1076 getpkt (buf);
1077
1078 if (buf[0] == 'E')
1079 perror ("Remote failure reply: %s", buf);
1080 }
1081
1082 /* Send a packet to the remote machine, with error checking.
1083 The data of the packet is in BUF. */
1084
1085 void
1086 putpkt (buf)
1087 char *buf;
1088 {
1089 int i;
1090 unsigned char csum = 0;
1091 char buf2[500];
1092 char buf3[1];
1093 int cnt = strlen (buf);
1094 char *p;
1095
1096 if (kiodebug)
1097 fprintf (stderr, "Sending packet: %s\n", buf);
1098
1099 /* Copy the packet into buffer BUF2, encapsulating it
1100 and giving it a checksum. */
1101
1102 p = buf2;
1103 *p++ = '$';
1104
1105 for (i = 0; i < cnt; i++)
1106 {
1107 csum += buf[i];
1108 *p++ = buf[i];
1109 }
1110 *p++ = '#';
1111 *p++ = tohex ((csum >> 4) & 0xf);
1112 *p++ = tohex (csum & 0xf);
1113
1114 /* Send it over and over until we get a positive ack. */
1115
1116 do {
1117 write (remote_desc, buf2, p - buf2);
1118 read (remote_desc, buf3, 1);
1119 } while (buf3[0] != '+');
1120 }
1121
1122 static int
1123 readchar ()
1124 {
1125 char buf[1];
1126 while (read (remote_desc, buf, 1) != 1) ;
1127 return buf[0] & 0x7f;
1128 }
1129
1130 /* Read a packet from the remote machine, with error checking,
1131 and store it in BUF. */
1132
1133 void
1134 getpkt (buf)
1135 char *buf;
1136 {
1137 char *bp;
1138 unsigned char csum, c, c1, c2;
1139 extern kiodebug;
1140
1141 while (1)
1142 {
1143 csum = 0;
1144 while ((c = readchar()) != '$');
1145
1146 bp = buf;
1147 while (1)
1148 {
1149 c = readchar ();
1150 if (c == '#')
1151 break;
1152 *bp++ = c;
1153 csum += c;
1154 }
1155 *bp = 0;
1156
1157 c1 = fromhex (readchar ());
1158 c2 = fromhex (readchar ());
1159 if (csum == (c1 << 4) + c2)
1160 break;
1161
1162 printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
1163 (c1 << 4) + c2, csum, buf);
1164 write (remote_desc, "-", 1);
1165 }
1166
1167 write (remote_desc, "+", 1);
1168
1169 if (kiodebug)
1170 fprintf (stderr,"Packet received :%s\n", buf);
1171 }
1172
1173
1174 void
1175 write_ok(buf)
1176 char *buf;
1177 {
1178 buf[0] = 'O';
1179 buf[1] = 'k';
1180 buf[2] = '\0';
1181 }
1182
1183 void
1184 write_enn(buf)
1185 char *buf;
1186 {
1187 buf[0] = 'E';
1188 buf[1] = 'N';
1189 buf[2] = 'N';
1190 buf[3] = '\0';
1191 }
1192
1193 void
1194 convert_int_to_ascii(from,to,n)
1195 char *from, *to; int n;
1196 {
1197 int nib ;
1198 char ch;
1199 while( n-- )
1200 {
1201 ch = *from++;
1202 nib = ((ch & 0xf0) >> 4)& 0x0f;
1203 *to++ = tohex(nib);
1204 nib = ch & 0x0f;
1205 *to++ = tohex(nib);
1206 }
1207 *to++ = 0;
1208 }
1209
1210
1211 void
1212 convert_ascii_to_int(from,to,n)
1213 char *from, *to; int n;
1214 {
1215 int nib1,nib2 ;
1216 while( n-- )
1217 {
1218 nib1 = fromhex(*from++);
1219 nib2 = fromhex(*from++);
1220 *to++ = (((nib1 & 0x0f)<< 4)& 0xf0) | (nib2 & 0x0f);
1221 }
1222 }
1223
1224 void
1225 prepare_resume_reply(buf,status,signal)
1226 char *buf ,status;
1227 unsigned char signal;
1228 {
1229 int nib;
1230 char ch;
1231
1232 *buf++ = 'S';
1233 *buf++ = status;
1234 nib = ((signal & 0xf0) >> 4) ;
1235 *buf++ = tohex(nib);
1236 nib = signal & 0x0f;
1237 *buf++ = tohex(nib);
1238 *buf++ = 0;
1239 }
1240
1241 void
1242 decode_m_packet(from,mem_addr_ptr,len_ptr)
1243 char *from;
1244 unsigned int *mem_addr_ptr, *len_ptr;
1245 {
1246 int i = 0, j = 0 ;
1247 char ch;
1248 *mem_addr_ptr = *len_ptr = 0;
1249 /************debugging begin************/
1250 printf("\nIn decode_m_packet");
1251 /************debugging end************/
1252
1253 while((ch = from[i++]) != ',')
1254 {
1255 *mem_addr_ptr = *mem_addr_ptr << 4;
1256 *mem_addr_ptr |= fromhex(ch) & 0x0f;
1257 }
1258 /************debugging begin************/
1259 printf("\nFinished mem_addr part");
1260 /************debugging end************/
1261
1262 for(j=0; j < 4; j++)
1263 {
1264 if((ch = from[i++]) == 0)
1265 break;
1266 *len_ptr = *len_ptr << 4;
1267 *len_ptr |= fromhex(ch) & 0x0f;
1268 }
1269 /************debugging begin************/
1270 printf("\nFinished len_ptr part");
1271 /************debugging end************/
1272 }
1273
1274 void
1275 decode_M_packet(from,mem_addr_ptr,len_ptr,to)
1276 char *from, *to;
1277 unsigned int *mem_addr_ptr, *len_ptr;
1278 {
1279 int i = 0, j = 0 ;
1280 char ch;
1281 *mem_addr_ptr = *len_ptr = 0;
1282 /************debugging begin************/
1283 printf("\nIn decode_M_packet");
1284 /************debugging end************/
1285
1286 while((ch = from[i++]) != ',')
1287 {
1288 *mem_addr_ptr = *mem_addr_ptr << 4;
1289 *mem_addr_ptr |= fromhex(ch) & 0x0f;
1290 }
1291 /************debugging begin************/
1292 printf("\nFinished mem_addr part: memaddr = %x",*mem_addr_ptr);
1293 /************debugging end************/
1294
1295 while((ch = from[i++]) != ':')
1296 {
1297 *len_ptr = *len_ptr << 4;
1298 *len_ptr |= fromhex(ch) & 0x0f;
1299 }
1300 /************debugging begin************/
1301 printf("\nFinished len_ptr part: len = %d",*len_ptr);
1302 /************debugging end************/
1303
1304 convert_ascii_to_int(&from[i++],to,*len_ptr);
1305
1306 /************debugging begin************/
1307 printf("\nmembuf : %x",*(int *)to);
1308 /************debugging end************/
1309 }
1310
1311 SHAR_EOF
1312 # End of shell archive
1313 exit 0
This page took 0.074333 seconds and 4 git commands to generate.