* scripttempl/mipsbsd.sc: Let sections align to their natural
[deliverable/binutils-gdb.git] / gdb / rem-multi.shar
CommitLineData
07d021a6
JG
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
12cat << \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#
99a7de40 18# This program is free software; you can redistribute it and/or modify
07d021a6 19# it under the terms of the GNU General Public License as published by
99a7de40
JG
20# the Free Software Foundation; either version 2 of the License, or
21# (at your option) any later version.
07d021a6 22#
99a7de40 23# This program is distributed in the hope that it will be useful,
07d021a6
JG
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
99a7de40
JG
29# along with this program; if not, write to the Free Software
30# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
07d021a6
JG
31
32CFLAGS = -g
33CC = cc
34
35SERVER = remote_server.o\
36 remote_inflow.o\
37 remote_utils.o\
38 remote_gutils.o
39
40prog : $(SERVER)
41 $(CC) -g -o serve $(SERVER)
42SHAR_EOF
43cat << \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
47This file is part of GDB.
48
99a7de40 49This program is free software; you can redistribute it and/or modify
07d021a6 50it under the terms of the GNU General Public License as published by
99a7de40
JG
51the Free Software Foundation; either version 2 of the License, or
52(at your option) any later version.
07d021a6 53
99a7de40 54This program is distributed in the hope that it will be useful,
07d021a6
JG
55but WITHOUT ANY WARRANTY; without even the implied warranty of
56MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57GNU General Public License for more details.
58
59You should have received a copy of the GNU General Public License
99a7de40
JG
60along with this program; if not, write to the Free Software
61Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
07d021a6
JG
62
63#include <stdio.h>
64#include <sys/ioctl.h>
65#include "defs.h"
66
67void error ();
68void fatal ();
69
70/* Chain of cleanup actions established with make_cleanup,
71 to be executed if an error happens. */
72
73static struct cleanup *cleanup_chain;
74
75/* Nonzero means a quit has been requested. */
76
77int quit_flag;
78
79/* Nonzero means quit immediately if Control-C is typed now,
80 rather than waiting until QUIT is executed. */
81
82int 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
89struct cleanup *
90make_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
109void
110do_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
125void
126discard_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
145void
146free_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
156char *
157xmalloc (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
168char *
169xrealloc (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
183void
184perror_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
209void
210print_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
232void
233quit ()
234{
235 fflush (stdout);
236 ioctl (fileno (stdout), TIOCFLUSH, 0);
237 error ("Quit");
238}
239
240/* Control C comes here */
241
242void
243request_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
254void
255error (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
269void
270fatal (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
284char *
285savestring (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
07d021a6
JG
295void
296print_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
309int
310query (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
352int
353parse_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
419void
420printchar (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}
451SHAR_EOF
452cat << \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*********************/
476int quit_flag = 0;
477char registers[REGISTER_BYTES];
478
479/* Index within `registers' of the first byte of the space for
480 register N. */
481
482
483char 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
491extern char **environ;
492extern int errno;
493extern int inferior_pid;
494void error(), quit(), perror_with_name();
495int query();
496void supply_register(), write_register();
497CORE_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
507int
508create_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
549kill_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
562unsigned char
563resume (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
603void
604fetch_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
634store_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
670read_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
699int
700write_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
743void
744try_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
770void
771initialize ()
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
783CORE_ADDR
784read_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
793void
794write_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
805int
806have_inferior_p ()
807{
808 return inferior_pid != 0;
809}
810
811print_some_registers(regs)
812int 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
820SHAR_EOF
821cat << \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
825This file is part of GDB.
826
99a7de40 827This program is free software; you can redistribute it and/or modify
07d021a6 828it under the terms of the GNU General Public License as published by
99a7de40
JG
829the Free Software Foundation; either version 2 of the License, or
830(at your option) any later version.
07d021a6 831
99a7de40 832This program is distributed in the hope that it will be useful,
07d021a6
JG
833but WITHOUT ANY WARRANTY; without even the implied warranty of
834MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
835GNU General Public License for more details.
836
837You should have received a copy of the GNU General Public License
99a7de40
JG
838along with this program; if not, write to the Free Software
839Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
07d021a6
JG
840
841#include "param.h"
842#include <stdio.h>
843
844void read_inferior_memory(), fetch_inferior_registers();
845unsigned char resume();
846void kill_inferior();
847void initialize(), try_writing_regs_command();
848int create_inferior(), read_register();
849
850extern char registers[];
851int inferior_pid;
852extern char **environ;
853
854/* Descriptor for I/O to remote machine. */
855int remote_desc;
856int kiodebug = 0;
857int remote_debugging;
858
859void remote_send ();
860void putpkt ();
861void getpkt ();
862void remote_open();
863void write_ok();
864void write_enn();
865void convert_ascii_to_int();
866void convert_int_to_ascii();
867void prepare_resume_reply();
868void decode_m_packet();
869void decode_M_packet();
870
871
872main(argc,argv)
873int 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
959SHAR_EOF
960cat << \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
964This file is part of GDB.
965
99a7de40 966This program is free software; you can redistribute it and/or modify
07d021a6 967it under the terms of the GNU General Public License as published by
99a7de40
JG
968the Free Software Foundation; either version 2 of the License, or
969(at your option) any later version.
07d021a6 970
99a7de40 971This program is distributed in the hope that it will be useful,
07d021a6
JG
972but WITHOUT ANY WARRANTY; without even the implied warranty of
973MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
974GNU General Public License for more details.
975
976You should have received a copy of the GNU General Public License
99a7de40
JG
977along with this program; if not, write to the Free Software
978Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
07d021a6
JG
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
989extern int remote_desc;
990extern int remote_debugging;
991extern int kiodebug;
992
993void remote_open();
994void remote_send();
995void putpkt();
996void getpkt();
997
998void write_ok();
999void write_enn();
1000void convert_ascii_to_int();
1001void convert_int_to_ascii();
1002void prepare_resume_reply();
1003
1004/* Open a connection to a remote debugger.
1005 NAME is the filename used for communication. */
1006
1007void
1008remote_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
1031static int
1032fromhex (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
1045static int
1046tohex (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
1059void
1060remote_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
1073void
1074putpkt (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
1110static int
1111readchar ()
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
1121void
1122getpkt (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
1162void
1163write_ok(buf)
1164 char *buf;
1165{
1166 buf[0] = 'O';
1167 buf[1] = 'k';
1168 buf[2] = '\0';
1169}
1170
1171void
1172write_enn(buf)
1173 char *buf;
1174{
1175 buf[0] = 'E';
1176 buf[1] = 'N';
1177 buf[2] = 'N';
1178 buf[3] = '\0';
1179}
1180
1181void
1182convert_int_to_ascii(from,to,n)
1183char *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
1199void
1200convert_ascii_to_int(from,to,n)
1201char *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
1212void
1213prepare_resume_reply(buf,status,signal)
1214char *buf ,status;
1215unsigned 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
1229void
1230decode_m_packet(from,mem_addr_ptr,len_ptr)
1231char *from;
1232unsigned 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
1262void
1263decode_M_packet(from,mem_addr_ptr,len_ptr,to)
1264char *from, *to;
1265unsigned 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
1299SHAR_EOF
1300# End of shell archive
1301exit 0
This page took 0.207793 seconds and 4 git commands to generate.