aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/remote-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver/remote-utils.c')
-rw-r--r--gdb/gdbserver/remote-utils.c545
1 files changed, 0 insertions, 545 deletions
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
deleted file mode 100644
index 5283404..0000000
--- a/gdb/gdbserver/remote-utils.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/* Remote utility routines for the remote server for GDB.
- Copyright (C) 1986, 1989, 1993 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "server.h"
-#include "terminal.h"
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/tcp.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-#include <fcntl.h>
-
-int remote_debug = 1;
-
-static int remote_desc;
-
-/* Open a connection to a remote debugger.
- NAME is the filename used for communication. */
-
-void
-remote_open (name)
- char *name;
-{
- int save_fcntl_flags;
-
- if (!strchr (name, ':'))
- {
- remote_desc = open (name, O_RDWR);
- if (remote_desc < 0)
- perror_with_name ("Could not open remote device");
-
-#ifdef HAVE_TERMIOS
- {
- struct termios termios;
- tcgetattr(remote_desc, &termios);
-
- termios.c_iflag = 0;
- termios.c_oflag = 0;
- termios.c_lflag = 0;
- termios.c_cflag &= ~(CSIZE|PARENB);
- termios.c_cflag |= CLOCAL | CS8;
- termios.c_cc[VMIN] = 0;
- termios.c_cc[VTIME] = 0;
-
- tcsetattr(remote_desc, TCSANOW, &termios);
- }
-#endif
-
-#ifdef HAVE_TERMIO
- {
- struct termio termio;
- ioctl (remote_desc, TCGETA, &termio);
-
- termio.c_iflag = 0;
- termio.c_oflag = 0;
- termio.c_lflag = 0;
- termio.c_cflag &= ~(CSIZE|PARENB);
- termio.c_cflag |= CLOCAL | CS8;
- termio.c_cc[VMIN] = 0;
- termio.c_cc[VTIME] = 0;
-
- ioctl (remote_desc, TCSETA, &termio);
- }
-#endif
-
-#ifdef HAVE_SGTTY
- {
- struct sgttyb sg;
-
- ioctl (remote_desc, TIOCGETP, &sg);
- sg.sg_flags = RAW;
- ioctl (remote_desc, TIOCSETP, &sg);
- }
-#endif
-
-
- }
- else
- {
- char *port_str;
- int port;
- struct sockaddr_in sockaddr;
- int tmp;
- struct protoent *protoent;
- int tmp_desc;
-
- port_str = strchr (name, ':');
-
- port = atoi (port_str + 1);
-
- tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
- if (tmp_desc < 0)
- perror_with_name ("Can't open socket");
-
- /* Allow rapid reuse of this port. */
- tmp = 1;
- setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
- sizeof(tmp));
-
- sockaddr.sin_family = PF_INET;
- sockaddr.sin_port = htons(port);
- sockaddr.sin_addr.s_addr = INADDR_ANY;
-
- if (bind (tmp_desc, (struct sockaddr *)&sockaddr, sizeof (sockaddr))
- || listen (tmp_desc, 1))
- perror_with_name ("Can't bind address");
-
- tmp = sizeof (sockaddr);
- remote_desc = accept (tmp_desc, (struct sockaddr *)&sockaddr, &tmp);
- if (remote_desc == -1)
- perror_with_name ("Accept failed");
-
- protoent = getprotobyname ("tcp");
- if (!protoent)
- perror_with_name ("getprotobyname");
-
- /* Enable TCP keep alive process. */
- tmp = 1;
- setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
-
- /* Tell TCP not to delay small packets. This greatly speeds up
- interactive response. */
- tmp = 1;
- setsockopt (remote_desc, protoent->p_proto, TCP_NODELAY,
- (char *)&tmp, sizeof(tmp));
-
- close (tmp_desc); /* No longer need this */
-
- signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
- exits when the remote side dies. */
- }
-
-#if defined(F_SETFL) && defined (FASYNC)
- save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
- fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
- disable_async_io ();
-#endif /* FASYNC */
- fprintf (stderr, "Remote debugging using %s\n", name);
-}
-
-void
-remote_close()
-{
- close (remote_desc);
-}
-
-/* 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
- error ("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 a packet to the remote machine, with error checking.
- The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
-
-int
-putpkt (buf)
- char *buf;
-{
- int i;
- unsigned char csum = 0;
- char buf2[2000];
- char buf3[1];
- int cnt = strlen (buf);
- char *p;
-
- /* 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);
-
- *p = '\0';
-
- /* Send it over and over until we get a positive ack. */
-
- do
- {
- int cc;
-
- if (write (remote_desc, buf2, p - buf2) != p - buf2)
- {
- perror ("putpkt(write)");
- return -1;
- }
-
- if (remote_debug)
- printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
- cc = read (remote_desc, buf3, 1);
- if (remote_debug)
- printf ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
- if (cc <= 0)
- {
- if (cc == 0)
- fprintf (stderr, "putpkt(read): Got EOF\n");
- else
- perror ("putpkt(read)");
-
- return -1;
- }
- }
- while (buf3[0] != '+');
-
- return 1; /* Success! */
-}
-
-/* Come here when we get an input interrupt from the remote side. This
- interrupt should only be active while we are waiting for the child to do
- something. About the only thing that should come through is a ^C, which
- will cause us to send a SIGINT to the child. */
-
-static void
-input_interrupt()
-{
- int cc;
- char c;
-
- cc = read (remote_desc, &c, 1);
-
- if (cc != 1 || c != '\003')
- {
- fprintf(stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
- return;
- }
-
- kill (inferior_pid, SIGINT);
-}
-
-void
-enable_async_io()
-{
- signal (SIGIO, input_interrupt);
-}
-
-void
-disable_async_io()
-{
- signal (SIGIO, SIG_IGN);
-}
-
-/* Returns next char from remote GDB. -1 if error. */
-
-static int
-readchar ()
-{
- static char buf[BUFSIZ];
- static int bufcnt = 0;
- static char *bufp;
-
- if (bufcnt-- > 0)
- return *bufp++ & 0x7f;
-
- bufcnt = read (remote_desc, buf, sizeof (buf));
-
- if (bufcnt <= 0)
- {
- if (bufcnt == 0)
- fprintf (stderr, "readchar: Got EOF\n");
- else
- perror ("readchar");
-
- return -1;
- }
-
- bufp = buf;
- bufcnt--;
- return *bufp++ & 0x7f;
-}
-
-/* Read a packet from the remote machine, with error checking,
- and store it in BUF. Returns length of packet, or negative if error. */
-
-int
-getpkt (buf)
- char *buf;
-{
- char *bp;
- unsigned char csum, c1, c2;
- int c;
-
- while (1)
- {
- csum = 0;
-
- while (1)
- {
- c = readchar ();
- if (c == '$')
- break;
- if (remote_debug)
- printf ("[getpkt: discarding char '%c']\n", c);
- if (c < 0)
- return -1;
- }
-
- bp = buf;
- while (1)
- {
- c = readchar ();
- if (c < 0)
- return -1;
- if (c == '#')
- break;
- *bp++ = c;
- csum += c;
- }
- *bp = 0;
-
- c1 = fromhex (readchar ());
- c2 = fromhex (readchar ());
-
- if (csum == (c1 << 4) + c2)
- break;
-
- fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
- (c1 << 4) + c2, csum, buf);
- write (remote_desc, "-", 1);
- }
-
- if (remote_debug)
- printf ("getpkt (\"%s\"); [sending ack] \n", buf);
-
- write (remote_desc, "+", 1);
-
- if (remote_debug)
- printf ("[sent ack]\n");
- return bp - 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);
- }
-}
-
-static char *
-outreg(regno, buf)
- int regno;
- char *buf;
-{
- extern char registers[];
- int regsize = REGISTER_RAW_SIZE (regno);
-
- *buf++ = tohex (regno >> 4);
- *buf++ = tohex (regno & 0xf);
- *buf++ = ':';
- convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, regsize);
- buf += 2 * regsize;
- *buf++ = ';';
-
- return buf;
-}
-
-void
-prepare_resume_reply (buf, status, signo)
- char *buf;
- char status;
- unsigned char signo;
-{
- int nib;
-
- *buf++ = status;
-
- /* FIXME! Should be converting this signal number (numbered
- according to the signal numbering of the system we are running on)
- to the signal numbers used by the gdb protocol (see enum target_signal
- in gdb/target.h). */
- nib = ((signo & 0xf0) >> 4);
- *buf++ = tohex (nib);
- nib = signo & 0x0f;
- *buf++ = tohex (nib);
-
- if (status == 'T')
- {
- buf = outreg (PC_REGNUM, buf);
- buf = outreg (FP_REGNUM, buf);
- buf = outreg (SP_REGNUM, buf);
-#ifdef NPC_REGNUM
- buf = outreg (NPC_REGNUM, buf);
-#endif
-#ifdef O7_REGNUM
- buf = outreg (O7_REGNUM, buf);
-#endif
-
- /* If the debugger hasn't used any thread features, don't burden it with
- threads. If we didn't check this, GDB 4.13 and older would choke. */
- if (cont_thread != 0)
- {
- if (old_thread_from_wait != thread_from_wait)
- {
- sprintf (buf, "thread:%x;", thread_from_wait);
- buf += strlen (buf);
- old_thread_from_wait = thread_from_wait;
- }
- }
- }
- /* For W and X, we're done. */
- *buf++ = 0;
-}
-
-void
-decode_m_packet (from, mem_addr_ptr, len_ptr)
- char *from;
- CORE_ADDR *mem_addr_ptr;
- unsigned int *len_ptr;
-{
- int i = 0, j = 0;
- char ch;
- *mem_addr_ptr = *len_ptr = 0;
-
- while ((ch = from[i++]) != ',')
- {
- *mem_addr_ptr = *mem_addr_ptr << 4;
- *mem_addr_ptr |= fromhex (ch) & 0x0f;
- }
-
- for (j = 0; j < 4; j++)
- {
- if ((ch = from[i++]) == 0)
- break;
- *len_ptr = *len_ptr << 4;
- *len_ptr |= fromhex (ch) & 0x0f;
- }
-}
-
-void
-decode_M_packet (from, mem_addr_ptr, len_ptr, to)
- char *from, *to;
- CORE_ADDR *mem_addr_ptr;
- unsigned int *len_ptr;
-{
- int i = 0;
- char ch;
- *mem_addr_ptr = *len_ptr = 0;
-
- while ((ch = from[i++]) != ',')
- {
- *mem_addr_ptr = *mem_addr_ptr << 4;
- *mem_addr_ptr |= fromhex (ch) & 0x0f;
- }
-
- while ((ch = from[i++]) != ':')
- {
- *len_ptr = *len_ptr << 4;
- *len_ptr |= fromhex (ch) & 0x0f;
- }
-
- convert_ascii_to_int (&from[i++], to, *len_ptr);
-}