#!/bin/sh
#	This is a shell archive.
#	Run the file through sh to extract its contents.
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Remote_Makefile
#	remote_gutils.c
#	remote_inflow.c
#	remote_server.c
#	remote_utils.c
# This archive created: Fri Jun 23 17:06:55 1989
cat << \SHAR_EOF > Remote_Makefile
#    Makefile for the remote server for GDB, the GNU debugger.
#    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
# 
# This file is part of GDB.
# 
# GDB is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 1, or (at your option)
# any later version.
# 
# GDB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GDB; see the file COPYING.  If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

CFLAGS = -g 
CC = cc

SERVER = remote_server.o\
		 remote_inflow.o\
		 remote_utils.o\
		 remote_gutils.o 

prog : $(SERVER)
	$(CC) -g -o serve $(SERVER) 
SHAR_EOF
cat << \SHAR_EOF > remote_gutils.c
/* General utility routines for the remote server for GDB, the GNU debugger.
   Copyright (C) 1986, 1989 Free Software Foundation, Inc.

This file is part of GDB.

GDB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GDB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <stdio.h>
#include <sys/ioctl.h>
#include "defs.h"

void error ();
void fatal ();

/* Chain of cleanup actions established with make_cleanup,
   to be executed if an error happens.  */

static struct cleanup *cleanup_chain;

/* Nonzero means a quit has been requested.  */

int quit_flag;

/* Nonzero means quit immediately if Control-C is typed now,
   rather than waiting until QUIT is executed.  */

int immediate_quit;

/* Add a new cleanup to the cleanup_chain,
   and return the previous chain pointer
   to be passed later to do_cleanups or discard_cleanups.
   Args are FUNCTION to clean up with, and ARG to pass to it.  */

struct cleanup *
make_cleanup (function, arg)
     void (*function) ();
     int arg;
{
  register struct cleanup *new
    = (struct cleanup *) xmalloc (sizeof (struct cleanup));
  register struct cleanup *old_chain = cleanup_chain;

  new->next = cleanup_chain;
  new->function = function;
  new->arg = arg;
  cleanup_chain = new;

  return old_chain;
}

/* Discard cleanups and do the actions they describe
   until we get back to the point OLD_CHAIN in the cleanup_chain.  */

void
do_cleanups (old_chain)
     register struct cleanup *old_chain;
{
  register struct cleanup *ptr;
  while ((ptr = cleanup_chain) != old_chain)
    {
      (*ptr->function) (ptr->arg);
      cleanup_chain = ptr->next;
      free (ptr);
    }
}

/* Discard cleanups, not doing the actions they describe,
   until we get back to the point OLD_CHAIN in the cleanup_chain.  */

void
discard_cleanups (old_chain)
     register struct cleanup *old_chain;
{
  register struct cleanup *ptr;
  while ((ptr = cleanup_chain) != old_chain)
    {
      cleanup_chain = ptr->next;
      free (ptr);
    }
}

/* This function is useful for cleanups.
   Do

     foo = xmalloc (...);
     old_chain = make_cleanup (free_current_contents, &foo);

   to arrange to free the object thus allocated.  */

void
free_current_contents (location)
     char **location;
{
  free (*location);
}

/* Generally useful subroutines used throughout the program.  */

/* Like malloc but get error if no storage available.  */

char *
xmalloc (size)
     long size;
{
  register char *val = (char *) malloc (size);
  if (!val)
    fatal ("virtual memory exhausted.", 0);
  return val;
}

/* Like realloc but get error if no storage available.  */

char *
xrealloc (ptr, size)
     char *ptr;
     long size;
{
  register char *val = (char *) realloc (ptr, size);
  if (!val)
    fatal ("virtual memory exhausted.", 0);
  return val;
}

/* Print the system error message for errno, and also mention STRING
   as the file name for which the error was encountered.
   Then return to command level.  */

void
perror_with_name (string)
     char *string;
{
  extern int sys_nerr;
  extern char *sys_errlist[];
  extern int errno;
  char *err;
  char *combined;

  if (errno < sys_nerr)
    err = sys_errlist[errno];
  else
    err = "unknown error";

  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  strcpy (combined, string);
  strcat (combined, ": ");
  strcat (combined, err);

  error ("%s.", combined);
}

/* Print the system error message for ERRCODE, and also mention STRING
   as the file name for which the error was encountered.  */

void
print_sys_errmsg (string, errcode)
     char *string;
     int errcode;
{
  extern int sys_nerr;
  extern char *sys_errlist[];
  char *err;
  char *combined;

  if (errcode < sys_nerr)
    err = sys_errlist[errcode];
  else
    err = "unknown error";

  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  strcpy (combined, string);
  strcat (combined, ": ");
  strcat (combined, err);

  printf ("%s.\n", combined);
}

void
quit ()
{
  fflush (stdout);
  ioctl (fileno (stdout), TIOCFLUSH, 0);
  error ("Quit");
}

/* Control C comes here */

void
request_quit ()
{
  quit_flag = 1;
  if (immediate_quit)
    quit ();
}

/* Print an error message and return to command level.
   STRING is the error message, used as a fprintf string,
   and ARG is passed as an argument to it.  */

void
error (string, arg1, arg2, arg3)
     char *string;
     int arg1, arg2, arg3;
{
  fflush (stdout);
  fprintf (stderr, string, arg1, arg2, arg3);
  fprintf (stderr, "\n");
  /************return_to_top_level ();************/ 
}

/* Print an error message and exit reporting failure.
   This is for a error that we cannot continue from.
   STRING and ARG are passed to fprintf.  */

void
fatal (string, arg)
     char *string;
     int arg;
{
  fprintf (stderr, "gdb: ");
  fprintf (stderr, string, arg);
  fprintf (stderr, "\n");
  exit (1);
}

/* Make a copy of the string at PTR with SIZE characters
   (and add a null character at the end in the copy).
   Uses malloc to get the space.  Returns the address of the copy.  */

char *
savestring (ptr, size)
     char *ptr;
     int size;
{
  register char *p = (char *) xmalloc (size + 1);
  bcopy (ptr, p, size);
  p[size] = 0;
  return p;
}

char *
concat (s1, s2, s3)
     char *s1, *s2, *s3;
{
  register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
  register char *val = (char *) xmalloc (len);
  strcpy (val, s1);
  strcat (val, s2);
  strcat (val, s3);
  return val;
}

void
print_spaces (n, file)
     register int n;
     register FILE *file;
{
  while (n-- > 0)
    fputc (' ', file);
}

/* Ask user a y-or-n question and return 1 iff answer is yes.
   Takes three args which are given to printf to print the question.
   The first, a control string, should end in "? ".
   It should not say how to answer, because we do that.  */

int
query (ctlstr, arg1, arg2)
     char *ctlstr;
{
  register int answer;

  /* Automatically answer "yes" if input is not from a terminal.  */
  /***********if (!input_from_terminal_p ())
    return 1; *************************/ 

  while (1)
    {
      printf (ctlstr, arg1, arg2);
      printf ("(y or n) ");
      fflush (stdout);
      answer = fgetc (stdin);
      clearerr (stdin);		/* in case of C-d */
      if (answer != '\n')
	while (fgetc (stdin) != '\n') clearerr (stdin);
      if (answer >= 'a')
	answer -= 040;
      if (answer == 'Y')
	return 1;
      if (answer == 'N')
	return 0;
      printf ("Please answer y or n.\n");
    }
}

/* Parse a C escape sequence.  STRING_PTR points to a variable
   containing a pointer to the string to parse.  That pointer
   is updated past the characters we use.  The value of the
   escape sequence is returned.

   A negative value means the sequence \ newline was seen,
   which is supposed to be equivalent to nothing at all.

   If \ is followed by a null character, we return a negative
   value and leave the string pointer pointing at the null character.

   If \ is followed by 000, we return 0 and leave the string pointer
   after the zeros.  A value of 0 does not mean end of string.  */

int
parse_escape (string_ptr)
     char **string_ptr;
{
  register int c = *(*string_ptr)++;
  switch (c)
    {
    case 'a':
      return '\a';
    case 'b':
      return '\b';
    case 'e':
      return 033;
    case 'f':
      return '\f';
    case 'n':
      return '\n';
    case 'r':
      return '\r';
    case 't':
      return '\t';
    case 'v':
      return '\v';
    case '\n':
      return -2;
    case 0:
      (*string_ptr)--;
      return 0;
    case '^':
      c = *(*string_ptr)++;
      if (c == '\\')
	c = parse_escape (string_ptr);
      if (c == '?')
	return 0177;
      return (c & 0200) | (c & 037);
      
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      {
	register int i = c - '0';
	register int count = 0;
	while (++count < 3)
	  {
	    if ((c = *(*string_ptr)++) >= '0' && c <= '7')
	      {
		i *= 8;
		i += c - '0';
	      }
	    else
	      {
		(*string_ptr)--;
		break;
	      }
	  }
	return i;
      }
    default:
      return c;
    }
}

void
printchar (ch, stream)
     unsigned char ch;
     FILE *stream;
{
  register int c = ch;
  if (c < 040 || c >= 0177)
    {
      if (c == '\n')
	fprintf (stream, "\\n");
      else if (c == '\b')
	fprintf (stream, "\\b");
      else if (c == '\t')
	fprintf (stream, "\\t");
      else if (c == '\f')
	fprintf (stream, "\\f");
      else if (c == '\r')
	fprintf (stream, "\\r");
      else if (c == 033)
	fprintf (stream, "\\e");
      else if (c == '\a')
	fprintf (stream, "\\a");
      else
	fprintf (stream, "\\%03o", c);
    }
  else
    {
      if (c == '\\' || c == '"' || c == '\'')
	fputc ('\\', stream);
      fputc (c, stream);
    }
}
SHAR_EOF
cat << \SHAR_EOF > remote_inflow.c
/* Low level interface to ptrace, for GDB when running under Unix.
   Copyright (C) 1986, 1987 Free Software Foundation, Inc.
*/

#include "defs.h"
#include "param.h"
#include "wait.h"
#include "frame.h"
#include "inferior.h"
/***************************
#include "initialize.h"
****************************/ 

#include <stdio.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sgtty.h>
#include <fcntl.h>

/***************Begin MY defs*********************/ 
int quit_flag = 0; 
char registers[REGISTER_BYTES]; 

/* Index within `registers' of the first byte of the space for
   register N.  */


char buf2[MAX_REGISTER_RAW_SIZE];
/***************End MY defs*********************/ 

#ifdef NEW_SUN_PTRACE
#include <sys/ptrace.h>
#include <machine/reg.h>
#endif

extern char **environ; 
extern int errno;
extern int inferior_pid; 
void error(), quit(), perror_with_name();
int query(); 
void supply_register(), write_register(); 
CORE_ADDR read_register(); 

/* Nonzero if we are debugging an attached outside process
   rather than an inferior.  */


/* Start an inferior process and returns its pid.
   ALLARGS is a vector of program-name and args.
   ENV is the environment vector to pass.  */

int
create_inferior (allargs, env)
     char **allargs;
     char **env;
{
  int pid;
  extern int sys_nerr;
  extern char *sys_errlist[];
  extern int errno;

  /* exec is said to fail if the executable is open.  */
  /****************close_exec_file ();*****************/ 

  pid = vfork ();
  if (pid < 0)
    perror_with_name ("vfork");

  if (pid == 0)
    {
      /* Run inferior in a separate process group.  */
      setpgrp (getpid (), getpid ());

/* Not needed on Sun, at least, and loses there
   because it clobbers the superior.  */
/*???      signal (SIGQUIT, SIG_DFL);
      signal (SIGINT, SIG_DFL);  */

	  errno = 0; 
      ptrace (0);

      execle ("/bin/sh", "sh", "-c", allargs, 0, env);

      fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
	       errno < sys_nerr ? sys_errlist[errno] : "unknown error");
      fflush (stderr);
      _exit (0177);
    }
  return pid;
}

/* Kill the inferior process.  Make us have no inferior.  */

kill_inferior ()
{
  if (inferior_pid == 0)
    return;
  ptrace (8, inferior_pid, 0, 0);
  wait (0);
  /*************inferior_died ();****VK**************/ 
}

/* Resume execution of the inferior process.
   If STEP is nonzero, single-step it.
   If SIGNAL is nonzero, give it that signal.  */

unsigned char
resume (step, signal,status)
     int step;
     int signal;
	 char *status; 
{
	int pid ; 
	WAITTYPE w; 

  	errno = 0;
    ptrace (step ? 9 : 7, inferior_pid, 1, signal);
    if (errno)
		perror_with_name ("ptrace");
	pid = wait(&w); 
	if(pid != inferior_pid) 
		perror_with_name ("wait"); 

	if(WIFEXITED(w))
	{
		printf("\nchild exited with retcode = %x \n",WRETCODE(w)); 
		*status = 'E'; 
		return((unsigned char) WRETCODE(w));
	} 
	else if(!WIFSTOPPED(w))
	{
		printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); 
		*status = 'T'; 
		return((unsigned char) WTERMSIG(w)); 
	} 
	else 
	{
		printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); 
		*status = 'S'; 
		return((unsigned char) WSTOPSIG(w)); 
	} 
		 
}


#ifdef NEW_SUN_PTRACE

void
fetch_inferior_registers ()
{
  struct regs inferior_registers;
  struct fp_status inferior_fp_registers;
  extern char registers[];

      ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
      if (errno)
		perror_with_name ("ptrace");
	  /**********debugging begin **********/ 
	  print_some_registers(&inferior_registers); 
	  /**********debugging end **********/ 
      ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
      if (errno)
		perror_with_name ("ptrace");

      bcopy (&inferior_registers, registers, 16 * 4);
      bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
	     sizeof inferior_fp_registers.fps_regs);
      *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
      *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
      bcopy (&inferior_fp_registers.fps_control,
	     &registers[REGISTER_BYTE (FPC_REGNUM)],
	     sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
}

/* Store our register values back into the inferior.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */

store_inferior_registers (regno)
     int regno;
{
  struct regs inferior_registers;
  struct fp_status inferior_fp_registers;
  extern char registers[];

      bcopy (registers, &inferior_registers, 16 * 4);
      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
	     sizeof inferior_fp_registers.fps_regs);
      inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
      inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
      bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
	     &inferior_fp_registers.fps_control,
	     sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);

      ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
      if (errno)
		perror_with_name ("ptrace");
      ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
      if (errno)
		perror_with_name ("ptrace");
}

#endif /* not NEW_SUN_PTRACE */


/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
   in the NEW_SUN_PTRACE case.
   It ought to be straightforward.  But it appears that writing did
   not write the data that I specified.  I cannot understand where
   it got the data that it actually did write.  */

/* Copy LEN bytes from inferior's memory starting at MEMADDR
   to debugger memory starting at MYADDR.  */

read_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     char *myaddr;
     int len;
{
  register int i;
  /* Round starting address down to longword boundary.  */
  register CORE_ADDR addr = memaddr & - sizeof (int);
  /* Round ending address up; get number of longwords that makes.  */
  register int count
    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  /* Allocate buffer of that many longwords.  */
  register int *buffer = (int *) alloca (count * sizeof (int));

  /* Read all the longwords */
  for (i = 0; i < count; i++, addr += sizeof (int))
    {
	buffer[i] = ptrace (1, inferior_pid, addr, 0);
    }

  /* Copy appropriate bytes out of the buffer.  */
  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
}

/* Copy LEN bytes of data from debugger memory at MYADDR
   to inferior's memory at MEMADDR.
   On failure (cannot write the inferior)
   returns the value of errno.  */

int
write_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     char *myaddr;
     int len;
{
  register int i;
  /* Round starting address down to longword boundary.  */
  register CORE_ADDR addr = memaddr & - sizeof (int);
  /* Round ending address up; get number of longwords that makes.  */
  register int count
    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  /* Allocate buffer of that many longwords.  */
  register int *buffer = (int *) alloca (count * sizeof (int));
  extern int errno;

  /* Fill start and end extra bytes of buffer with existing memory data.  */

    buffer[0] = ptrace (1, inferior_pid, addr, 0);

  if (count > 1)
    {
	buffer[count - 1]
	  = ptrace (1, inferior_pid,
		    addr + (count - 1) * sizeof (int), 0);
    }

  /* Copy data to be written over corresponding part of buffer */

  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);

  /* Write the entire buffer.  */

  for (i = 0; i < count; i++, addr += sizeof (int))
    {
      errno = 0;
	ptrace (4, inferior_pid, addr, buffer[i]);
      if (errno)
	return errno;
    }

  return 0;
}

void
try_writing_regs_command ()
{
  register int i;
  register int value;
  extern int errno;

  if (inferior_pid == 0)
    error ("There is no inferior process now.");

  fetch_inferior_registers(); 
  for (i = 0;i<18 ; i ++)
    {
      QUIT;
      errno = 0;
      value = read_register(i); 
      write_register ( i, value);
      if (errno == 0)
	{
	  	printf (" Succeeded with register %d; value 0x%x (%d).\n",
		  i, value, value);
	}
      else 
		printf (" Failed with register %d.\n", i);
    }
}

void
initialize ()
{

  inferior_pid = 0;


}


/* Return the contents of register REGNO,
   regarding it as an integer.  */

CORE_ADDR
read_register (regno)
     int regno;
{
  /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  return *(int *) &registers[REGISTER_BYTE (regno)];
}

/* Store VALUE in the register number REGNO, regarded as an integer.  */

void
write_register (regno, val)
     int regno, val;
{
  /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  *(int *) &registers[REGISTER_BYTE (regno)] = val;

  if (have_inferior_p ())
    store_inferior_registers (regno);
}


int
have_inferior_p ()
{
  return inferior_pid != 0;
}

print_some_registers(regs)
int regs[];
{
   register int i;
   for (i = 0; i < 18; i++) {
	 printf("reg[%d] = %x\n", i, regs[i]);
	 }
}

SHAR_EOF
cat << \SHAR_EOF > remote_server.c
/* Main code for remote server for GDB, the GNU Debugger.
   Copyright (C) 1989 Free Software Foundation, Inc.

This file is part of GDB.

GDB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GDB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "param.h"
#include <stdio.h>

void read_inferior_memory(), fetch_inferior_registers(); 
unsigned char resume(); 
void kill_inferior(); 
void initialize(), try_writing_regs_command();  
int create_inferior(), read_register(); 

extern char registers[]; 
int inferior_pid; 
extern char **environ; 

/* Descriptor for I/O to remote machine.  */
int remote_desc;
int kiodebug = 0;
int remote_debugging; 

void remote_send ();
void putpkt ();
void getpkt ();
void remote_open(); 
void write_ok(); 
void write_enn(); 
void convert_ascii_to_int(); 
void convert_int_to_ascii(); 
void prepare_resume_reply(); 
void decode_m_packet(); 
void decode_M_packet(); 


main(argc,argv)
int argc; char *argv[]; 
{
    char ch,status, own_buf[2000], mem_buf[2000]; 
	int i=0;  
	unsigned char signal;  
	unsigned int mem_addr, len; 

	initialize(); 
    printf("\nwill open serial link\n"); 
    remote_open("/dev/ttya",0); 

	if(argc < 2) 
	{ 
		printf("Enter name of program to be run with command line args\n"); 
		gets(own_buf); 
		inferior_pid = create_inferior(own_buf,environ); 
		printf("\nProcess %s created; pid = %d\n",own_buf,inferior_pid);
	} 
	else 
	{ 
		inferior_pid = create_inferior(argv[1],environ); 
		printf("\nProcess %s created; pid = %d\n",argv[1],inferior_pid);
	} 

    do {  
        getpkt(own_buf); 
        printf("\nPacket received is>:%s\n",own_buf); 
		i = 0; 
		ch = own_buf[i++]; 
	    switch (ch) { 
			case 'h':	/**********This is only for tweaking the gdb+ program *******/ 
						signal = resume(1,0,&status);
						prepare_resume_reply(own_buf,status,signal); 
						break; 
						/*************end tweak*************************************/ 

			case 'g':	fetch_inferior_registers(); 		
						convert_int_to_ascii(registers,own_buf,REGISTER_BYTES); 
						break; 
			case 'G':	convert_ascii_to_int(&own_buf[1],registers,REGISTER_BYTES);
						if(store_inferior_registers(-1)==0)  
							write_ok(own_buf); 
						else  
							write_enn(own_buf); 
						break; 
			case 'm':	decode_m_packet(&own_buf[1],&mem_addr,&len); 
						read_inferior_memory(mem_addr,mem_buf,len);
						convert_int_to_ascii(mem_buf,own_buf,len); 
						break; 
			case 'M':	decode_M_packet(&own_buf[1],&mem_addr,&len,mem_buf); 
						if(write_inferior_memory(mem_addr,mem_buf,len)==0)  
							write_ok(own_buf); 
						else 
							write_enn(own_buf); 
						break; 
			case 'c':	signal = resume(0,0,&status);
						printf("\nSignal received is >: %0x \n",signal); 
						prepare_resume_reply(own_buf,status,signal); 
						break; 
			case 's':	signal = resume(1,0,&status);
						prepare_resume_reply(own_buf,status,signal); 
						break; 
			case 'k':	kill_inferior();
						sprintf(own_buf,"q"); 
        				putpkt(own_buf); 
						printf("\nObtained kill request...terminating\n"); 
     					close(remote_desc); 
						exit(0); 
			case 't':	try_writing_regs_command();
						own_buf[0] = '\0'; 
						break; 
			default :	printf("\nUnknown option chosen by master\n"); 
						write_enn(own_buf); 
						break; 
 		  } 

        putpkt(own_buf); 
     }  while(1) ; 

    close(remote_desc); 
    /** now get out of here**/ 
    printf("\nFinished reading data from serial link - Bye!\n"); 
    exit(0);

}

SHAR_EOF
cat << \SHAR_EOF > remote_utils.c
/* Remote utility routines for the remote server for GDB, the GNU debugger.
   Copyright (C) 1986, 1989 Free Software Foundation, Inc.

This file is part of GDB.

GDB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GDB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "param.h"
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <a.out.h>
#include <sys/file.h>
#include <sgtty.h> 

extern int remote_desc; 
extern int remote_debugging; 
extern int kiodebug; 

void remote_open(); 
void remote_send(); 
void putpkt(); 
void getpkt(); 

void write_ok(); 
void write_enn(); 
void convert_ascii_to_int(); 
void convert_int_to_ascii(); 
void prepare_resume_reply(); 

/* Open a connection to a remote debugger.
   NAME is the filename used for communication.  */

void
remote_open (name, from_tty)
     char *name;
     int from_tty;
{
  struct sgttyb sg;

  remote_debugging = 0;

  remote_desc = open (name, O_RDWR);
  if (remote_desc < 0)
    printf("\ncould not open remote device\n"); 

  ioctl (remote_desc, TIOCGETP, &sg);
  sg.sg_flags = RAW;
  ioctl (remote_desc, TIOCSETP, &sg);

  if (from_tty)
    printf ("Remote debugging using %s\n", name);
  remote_debugging = 1;
}

/* Convert hex digit A to a number.  */

static int
fromhex (a)
     int a;
{
  if (a >= '0' && a <= '9')
    return a - '0';
  else if (a >= 'a' && a <= 'f')
    return a - 'a' + 10;
  else
    perror ("Reply contains invalid hex digit");
}

/* Convert number NIB to a hex digit.  */

static int
tohex (nib)
     int nib;
{
  if (nib < 10)
    return '0'+nib;
  else
    return 'a'+nib-10;
}

/* Send the command in BUF to the remote machine,
   and read the reply into BUF.
   Report an error if we get an error reply.  */

void
remote_send (buf)
     char *buf;
{
  putpkt (buf);
  getpkt (buf);

  if (buf[0] == 'E')
    perror ("Remote failure reply: %s", buf);
}

/* Send a packet to the remote machine, with error checking.
   The data of the packet is in BUF.  */

void
putpkt (buf)
     char *buf;
{
  int i;
  unsigned char csum = 0;
  char buf2[500];
  char buf3[1];
  int cnt = strlen (buf);
  char *p;

  if (kiodebug)
    fprintf (stderr, "Sending packet: %s\n", buf);

  /* Copy the packet into buffer BUF2, encapsulating it
     and giving it a checksum.  */

  p = buf2;
  *p++ = '$';

  for (i = 0; i < cnt; i++)
    {
      csum += buf[i];
      *p++ = buf[i];
    }
  *p++ = '#';
  *p++ = tohex ((csum >> 4) & 0xf);
  *p++ = tohex (csum & 0xf);

  /* Send it over and over until we get a positive ack.  */

  do {
    write (remote_desc, buf2, p - buf2);
    read (remote_desc, buf3, 1);
  } while (buf3[0] != '+');
}

static int
readchar ()
{
  char buf[1];
  while (read (remote_desc, buf, 1) != 1) ;
  return buf[0] & 0x7f;
}

/* Read a packet from the remote machine, with error checking,
   and store it in BUF.  */

void
getpkt (buf)
     char *buf;
{
  char *bp;
  unsigned char csum, c, c1, c2;
  extern kiodebug;

  while (1)
    {
	  csum = 0; 
      while ((c = readchar()) != '$');

      bp = buf;
      while (1)
	{
	  c = readchar ();
	  if (c == '#')
	    break;
	  *bp++ = c;
	  csum += c;
	}
      *bp = 0;

      c1 = fromhex (readchar ());
      c2 = fromhex (readchar ());
      if (csum == (c1 << 4) + c2)
	    break;

      printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
	      (c1 << 4) + c2, csum, buf);
      write (remote_desc, "-", 1);
    }

  write (remote_desc, "+", 1);

  if (kiodebug)
    fprintf (stderr,"Packet received :%s\n", buf);
}


void 
write_ok(buf)
	char *buf; 
{
	buf[0] = 'O';
	buf[1] = 'k';
	buf[2] = '\0';
}

void 
write_enn(buf)
	char *buf; 
{
	buf[0] = 'E';
	buf[1] = 'N';
	buf[2] = 'N';
	buf[3] = '\0';
}

void
convert_int_to_ascii(from,to,n)
char *from, *to; int n; 
{
 	int nib ; 
	char ch; 
	while( n-- )
	{
		ch = *from++; 		
		nib = ((ch & 0xf0) >> 4)& 0x0f; 
		*to++ = tohex(nib); 
		nib = ch & 0x0f; 
		*to++ = tohex(nib); 
	} 
	*to++ = 0; 
}


void
convert_ascii_to_int(from,to,n)
char *from, *to; int n;  
{
 	int nib1,nib2 ; 
	while( n-- )
	{
		nib1 = fromhex(*from++); 
		nib2 = fromhex(*from++); 
		*to++ = (((nib1 & 0x0f)<< 4)& 0xf0) | (nib2 & 0x0f); 
	} 
}

void
prepare_resume_reply(buf,status,signal)
char *buf ,status; 
unsigned char signal; 
{
 	int nib; 
	char ch; 

	*buf++ = 'S';  
	*buf++ = status;  
	nib = ((signal & 0xf0) >> 4) ; 
	*buf++ = tohex(nib); 
	nib = signal & 0x0f; 
	*buf++ = tohex(nib); 
	*buf++ = 0; 
}

void 
decode_m_packet(from,mem_addr_ptr,len_ptr)
char *from;
unsigned int *mem_addr_ptr, *len_ptr; 
{
	int i = 0, j = 0 ; 
	char ch; 
	*mem_addr_ptr = *len_ptr = 0; 
	/************debugging begin************/ 
	printf("\nIn decode_m_packet"); 
	/************debugging end************/ 

	while((ch = from[i++]) != ',') 
	{ 
		*mem_addr_ptr = *mem_addr_ptr << 4; 
		*mem_addr_ptr |= fromhex(ch) & 0x0f; 
	} 
	/************debugging begin************/ 
	printf("\nFinished mem_addr part"); 
	/************debugging end************/ 

	for(j=0; j < 4; j++) 
	{ 
		if((ch = from[i++]) == 0)  
			break; 
		*len_ptr = *len_ptr << 4; 
		*len_ptr |= fromhex(ch) & 0x0f; 
	} 
	/************debugging begin************/ 
	printf("\nFinished len_ptr part"); 
	/************debugging end************/ 
}

void 
decode_M_packet(from,mem_addr_ptr,len_ptr,to)
char *from, *to;
unsigned int *mem_addr_ptr, *len_ptr; 
{
	int i = 0, j = 0 ; 
	char ch; 
	*mem_addr_ptr = *len_ptr = 0; 
	/************debugging begin************/ 
	printf("\nIn decode_M_packet"); 
	/************debugging end************/ 

	while((ch = from[i++]) != ',') 
	{ 
		*mem_addr_ptr = *mem_addr_ptr << 4; 
		*mem_addr_ptr |= fromhex(ch) & 0x0f; 
	} 
	/************debugging begin************/ 
	printf("\nFinished mem_addr part: memaddr = %x",*mem_addr_ptr); 
	/************debugging end************/ 

	while((ch = from[i++]) != ':') 
	{ 
		*len_ptr = *len_ptr << 4; 
		*len_ptr |= fromhex(ch) & 0x0f; 
	} 
	/************debugging begin************/ 
	printf("\nFinished len_ptr part: len = %d",*len_ptr); 
	/************debugging end************/ 

	convert_ascii_to_int(&from[i++],to,*len_ptr); 

	/************debugging begin************/ 
	printf("\nmembuf : %x",*(int *)to); 
	/************debugging end************/ 
}

SHAR_EOF
#	End of shell archive
exit 0
