along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include "server.h"
#include <stdio.h>
-#include <sys/ioctl.h>
-#include "defs.h"
-#include <setjmp.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;
-\f
-/* 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) ();
- PTR 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);
-}
-\f
/* Generally useful subroutines used throughout the program. */
-/* Like malloc but get error if no storage available. */
-
-PTR
-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. */
-
-PTR
-xrealloc (ptr, size)
- PTR 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. */
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 (ignored)
- int ignored;
-{
- 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. */
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)
- const 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");
- }
-}
-\f
-/* 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;
- }
-}
-\f
-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);
- }
-}
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include "defs.h"
+#include "server.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>*/
#define LYNXOS
#include <sys/mem.h>
#include <sys/signal.h>
#include <fcntl.h>
#include "/usr/include/wait.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*********************/
-
#include <sys/ptrace.h>
-/*#include <machine/reg.h>*/
-
-extern char **environ;
-extern int errno;
-extern int inferior_pid;
-void error (), quit (), perror_with_name ();
-int query ();
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args.
{
if (inferior_pid == 0)
return;
- ptrace (8, inferior_pid, 0, 0);
+ ptrace (PTRACE_KILL, inferior_pid, 0, 0);
wait (0);
- /*************inferior_died ();****VK**************/
+
+ inferior_pid = 0;
}
/* Wait for process, returns status */
int pid;
union wait w;
+ enable_async_io();
+
pid = wait (&w);
+
+ disable_async_io();
+
if (pid != PIDGET(inferior_pid))
perror_with_name ("wait");
if (WIFEXITED (w))
{
- fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
- *status = 'E';
- return ((unsigned char) WEXITSTATUS (w));
+ fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w));
+ fprintf (stderr, "GDBserver exiting\n");
+ exit (0);
}
else if (!WIFSTOPPED (w))
{
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */
+void
read_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
/* Read all the longwords */
for (i = 0; i < count; i++, addr += sizeof (int))
{
- buffer[i] = ptrace (1, inferior_pid, addr, 0);
+ buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
}
/* Copy appropriate bytes out of the buffer. */
/* Fill start and end extra bytes of buffer with existing memory data. */
- buffer[0] = ptrace (1, inferior_pid, addr, 0);
+ buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
if (count > 1)
{
buffer[count - 1]
- = ptrace (1, inferior_pid,
+ = ptrace (PTRACE_PEEKTEXT, inferior_pid,
addr + (count - 1) * sizeof (int), 0);
}
for (i = 0; i < count; i++, addr += sizeof (int))
{
errno = 0;
- ptrace (4, inferior_pid, addr, buffer[i]);
+ ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
if (errno)
return errno;
}
return 0;
}
-\f
-void
-initialize ()
-{
- inferior_pid = 0;
-}
-
-int
-have_inferior_p ()
-{
- return inferior_pid != 0;
-}
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include "defs.h"
-#include <setjmp.h>
-#include <signal.h>
-
-void read_inferior_memory ();
-unsigned char mywait ();
-void myresume();
-void initialize ();
-int create_inferior ();
-
-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 ();
-jmp_buf toplevel;
+#include "server.h"
main (argc, argv)
int argc;
if (argc < 3)
error("Usage: gdbserver tty prog [args ...]");
- initialize ();
- remote_open (argv[1], 0);
-
inferior_pid = create_inferior (argv[2], &argv[2]);
fprintf (stderr, "Process %s created; pid = %d\n", argv[2], inferior_pid);
/* We are now stopped at the first instruction of the target process */
- setjmp(toplevel);
- do
+ while (1)
{
- getpkt (own_buf);
- i = 0;
- ch = own_buf[i++];
- switch (ch)
+ remote_open (argv[1]);
+
+ setjmp(toplevel);
+ while (getpkt (own_buf) > 0)
{
- case '?':
- prepare_resume_reply (own_buf, status, signal);
- break;
- case 'g':
- convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
- break;
- case 'G':
- convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
- store_inferior_registers (-1);
- write_ok (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':
- myresume (0, 0);
- signal = mywait (&status);
- prepare_resume_reply (own_buf, status, signal);
- break;
- case 's':
- myresume (1, 0);
- signal = mywait (&status);
- prepare_resume_reply (own_buf, status, signal);
- break;
- case 'k':
- kill_inferior ();
- sprintf (own_buf, "q");
+ i = 0;
+ ch = own_buf[i++];
+ switch (ch)
+ {
+ case '?':
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'g':
+ convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
+ break;
+ case 'G':
+ convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
+ store_inferior_registers (-1);
+ write_ok (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':
+ myresume (0, 0);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 's':
+ myresume (1, 0);
+ signal = mywait (&status);
+ prepare_resume_reply (own_buf, status, signal);
+ break;
+ case 'k':
+ fprintf (stderr, "Killing inferior\n");
+ kill_inferior ();
+ inferior_pid = create_inferior (argv[2], &argv[2]);
+ fprintf (stderr, "Process %s created; pid = %d\n", argv[2],
+ inferior_pid);
+ signal = mywait (&status); /* Wait till we are at 1st instr in prog */
+ break;
+ default:
+ printf ("\nUnknown option chosen by master\n");
+ write_enn (own_buf);
+ break;
+ }
+
putpkt (own_buf);
- fprintf (stderr, "Obtained kill request...terminating\n");
- close (remote_desc);
- exit (0);
- default:
- printf ("\nUnknown option chosen by master\n");
- write_enn (own_buf);
- break;
}
- putpkt (own_buf);
- }
- while (1);
+ /* We come here when getpkt fails. Close the connection, and re-open it
+ at the top of the loop. */
+
+ fprintf (stderr, "Remote side has terminated connection. GDBserver will reopen the connection.\n");
- close (remote_desc);
- /** now get out of here**/
- fprintf (stderr, "Finished reading data from serial link - Bye!\n");
- exit (0);
+ remote_close ();
+ }
}