#!/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. # # This program 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 2 of the License, or # (at your option) any later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 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. This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #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; } 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 #include #include #include #include #include #include #include /***************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 #include #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, ®isters[REGISTER_BYTE (FP0_REGNUM)], sizeof inferior_fp_registers.fps_regs); *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; bcopy (&inferior_fp_registers.fps_control, ®isters[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 (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, sizeof inferior_fp_registers.fps_regs); inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; bcopy (®isters[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 *) ®isters[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 *) ®isters[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. This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "param.h" #include 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. This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "param.h" #include #include #include #include #include #include #include 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