Change the stream argument to _filtered to GDB_FILE *.
[deliverable/binutils-gdb.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.058814 seconds and 4 git commands to generate.