119370Spst/* Remote utility routines for the remote server for GDB.
298944Sobrien   Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3130803Smarcel   2002, 2003, 2004
498944Sobrien   Free Software Foundation, Inc.
519370Spst
698944Sobrien   This file is part of GDB.
719370Spst
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1219370Spst
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1719370Spst
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "server.h"
2446283Sdfr#include "terminal.h"
2519370Spst#include <stdio.h>
2646283Sdfr#include <string.h>
2746283Sdfr#include <sys/ioctl.h>
2819370Spst#include <sys/file.h>
2919370Spst#include <netinet/in.h>
3019370Spst#include <sys/socket.h>
3119370Spst#include <netdb.h>
3219370Spst#include <netinet/tcp.h>
3319370Spst#include <sys/ioctl.h>
3419370Spst#include <signal.h>
3546283Sdfr#include <fcntl.h>
3698944Sobrien#include <sys/time.h>
3798944Sobrien#include <unistd.h>
38130803Smarcel#include <arpa/inet.h>
3919370Spst
4046283Sdfrint remote_debug = 0;
4198944Sobrienstruct ui_file *gdb_stdlog;
4246283Sdfr
4319370Spststatic int remote_desc;
4419370Spst
45130803Smarcel/* FIXME headerize? */
46130803Smarcelextern int using_threads;
47130803Smarcelextern int debug_threads;
48130803Smarcel
4919370Spst/* Open a connection to a remote debugger.
5019370Spst   NAME is the filename used for communication.  */
5119370Spst
5219370Spstvoid
5398944Sobrienremote_open (char *name)
5419370Spst{
5546283Sdfr  int save_fcntl_flags;
5698944Sobrien
5719370Spst  if (!strchr (name, ':'))
5819370Spst    {
5919370Spst      remote_desc = open (name, O_RDWR);
6019370Spst      if (remote_desc < 0)
6119370Spst	perror_with_name ("Could not open remote device");
6219370Spst
6346283Sdfr#ifdef HAVE_TERMIOS
6446283Sdfr      {
6546283Sdfr	struct termios termios;
6698944Sobrien	tcgetattr (remote_desc, &termios);
6746283Sdfr
6846283Sdfr	termios.c_iflag = 0;
6946283Sdfr	termios.c_oflag = 0;
7046283Sdfr	termios.c_lflag = 0;
7198944Sobrien	termios.c_cflag &= ~(CSIZE | PARENB);
7246283Sdfr	termios.c_cflag |= CLOCAL | CS8;
7398944Sobrien	termios.c_cc[VMIN] = 1;
7446283Sdfr	termios.c_cc[VTIME] = 0;
7546283Sdfr
7698944Sobrien	tcsetattr (remote_desc, TCSANOW, &termios);
7746283Sdfr      }
7846283Sdfr#endif
7946283Sdfr
8046283Sdfr#ifdef HAVE_TERMIO
8146283Sdfr      {
8246283Sdfr	struct termio termio;
8346283Sdfr	ioctl (remote_desc, TCGETA, &termio);
8446283Sdfr
8546283Sdfr	termio.c_iflag = 0;
8646283Sdfr	termio.c_oflag = 0;
8746283Sdfr	termio.c_lflag = 0;
8898944Sobrien	termio.c_cflag &= ~(CSIZE | PARENB);
8946283Sdfr	termio.c_cflag |= CLOCAL | CS8;
9098944Sobrien	termio.c_cc[VMIN] = 1;
9146283Sdfr	termio.c_cc[VTIME] = 0;
9246283Sdfr
9346283Sdfr	ioctl (remote_desc, TCSETA, &termio);
9446283Sdfr      }
9546283Sdfr#endif
9646283Sdfr
9746283Sdfr#ifdef HAVE_SGTTY
9846283Sdfr      {
9946283Sdfr	struct sgttyb sg;
10046283Sdfr
10146283Sdfr	ioctl (remote_desc, TIOCGETP, &sg);
10246283Sdfr	sg.sg_flags = RAW;
10346283Sdfr	ioctl (remote_desc, TIOCSETP, &sg);
10446283Sdfr      }
10546283Sdfr#endif
10646283Sdfr
10798944Sobrien      fprintf (stderr, "Remote debugging using %s\n", name);
10819370Spst    }
10919370Spst  else
11019370Spst    {
11119370Spst      char *port_str;
11219370Spst      int port;
11319370Spst      struct sockaddr_in sockaddr;
11419370Spst      int tmp;
11519370Spst      int tmp_desc;
11619370Spst
11719370Spst      port_str = strchr (name, ':');
11819370Spst
11919370Spst      port = atoi (port_str + 1);
12019370Spst
12119370Spst      tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
12219370Spst      if (tmp_desc < 0)
12319370Spst	perror_with_name ("Can't open socket");
12419370Spst
12519370Spst      /* Allow rapid reuse of this port. */
12619370Spst      tmp = 1;
12798944Sobrien      setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
12898944Sobrien		  sizeof (tmp));
12919370Spst
13019370Spst      sockaddr.sin_family = PF_INET;
13198944Sobrien      sockaddr.sin_port = htons (port);
13219370Spst      sockaddr.sin_addr.s_addr = INADDR_ANY;
13319370Spst
13498944Sobrien      if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
13519370Spst	  || listen (tmp_desc, 1))
13619370Spst	perror_with_name ("Can't bind address");
13719370Spst
138130803Smarcel      fprintf (stderr, "Listening on port %d\n", port);
139130803Smarcel
14019370Spst      tmp = sizeof (sockaddr);
14198944Sobrien      remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
14219370Spst      if (remote_desc == -1)
14319370Spst	perror_with_name ("Accept failed");
14419370Spst
14519370Spst      /* Enable TCP keep alive process. */
14619370Spst      tmp = 1;
14798944Sobrien      setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
14819370Spst
14919370Spst      /* Tell TCP not to delay small packets.  This greatly speeds up
15098944Sobrien         interactive response. */
15119370Spst      tmp = 1;
15298944Sobrien      setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
15398944Sobrien		  (char *) &tmp, sizeof (tmp));
15419370Spst
15519370Spst      close (tmp_desc);		/* No longer need this */
15619370Spst
15798944Sobrien      signal (SIGPIPE, SIG_IGN);	/* If we don't do this, then gdbserver simply
15898944Sobrien					   exits when the remote side dies.  */
15998944Sobrien
16098944Sobrien      /* Convert IP address to string.  */
16198944Sobrien      fprintf (stderr, "Remote debugging from host %s\n",
16298944Sobrien         inet_ntoa (sockaddr.sin_addr));
16319370Spst    }
16419370Spst
16546283Sdfr#if defined(F_SETFL) && defined (FASYNC)
16646283Sdfr  save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
16746283Sdfr  fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
16898944Sobrien#if defined (F_SETOWN)
16998944Sobrien  fcntl (remote_desc, F_SETOWN, getpid ());
17098944Sobrien#endif
17198944Sobrien#endif
17246283Sdfr  disable_async_io ();
17319370Spst}
17419370Spst
17519370Spstvoid
17698944Sobrienremote_close (void)
17719370Spst{
17819370Spst  close (remote_desc);
17919370Spst}
18019370Spst
18119370Spst/* Convert hex digit A to a number.  */
18219370Spst
18319370Spststatic int
18498944Sobrienfromhex (int a)
18519370Spst{
18619370Spst  if (a >= '0' && a <= '9')
18719370Spst    return a - '0';
18819370Spst  else if (a >= 'a' && a <= 'f')
18919370Spst    return a - 'a' + 10;
19019370Spst  else
19119370Spst    error ("Reply contains invalid hex digit");
19298944Sobrien  return 0;
19319370Spst}
19419370Spst
195130803Smarcelint
196130803Smarcelunhexify (char *bin, const char *hex, int count)
197130803Smarcel{
198130803Smarcel  int i;
199130803Smarcel
200130803Smarcel  for (i = 0; i < count; i++)
201130803Smarcel    {
202130803Smarcel      if (hex[0] == 0 || hex[1] == 0)
203130803Smarcel        {
204130803Smarcel          /* Hex string is short, or of uneven length.
205130803Smarcel             Return the count that has been converted so far. */
206130803Smarcel          return i;
207130803Smarcel        }
208130803Smarcel      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
209130803Smarcel      hex += 2;
210130803Smarcel    }
211130803Smarcel  return i;
212130803Smarcel}
213130803Smarcel
214130803Smarcelstatic void
215130803Smarceldecode_address (CORE_ADDR *addrp, const char *start, int len)
216130803Smarcel{
217130803Smarcel  CORE_ADDR addr;
218130803Smarcel  char ch;
219130803Smarcel  int i;
220130803Smarcel
221130803Smarcel  addr = 0;
222130803Smarcel  for (i = 0; i < len; i++)
223130803Smarcel    {
224130803Smarcel      ch = start[i];
225130803Smarcel      addr = addr << 4;
226130803Smarcel      addr = addr | (fromhex (ch) & 0x0f);
227130803Smarcel    }
228130803Smarcel  *addrp = addr;
229130803Smarcel}
230130803Smarcel
23119370Spst/* Convert number NIB to a hex digit.  */
23219370Spst
23319370Spststatic int
23498944Sobrientohex (int nib)
23519370Spst{
23619370Spst  if (nib < 10)
23719370Spst    return '0' + nib;
23819370Spst  else
23919370Spst    return 'a' + nib - 10;
24019370Spst}
24119370Spst
242130803Smarcelint
243130803Smarcelhexify (char *hex, const char *bin, int count)
244130803Smarcel{
245130803Smarcel  int i;
246130803Smarcel
247130803Smarcel  /* May use a length, or a nul-terminated string as input. */
248130803Smarcel  if (count == 0)
249130803Smarcel    count = strlen (bin);
250130803Smarcel
251130803Smarcel  for (i = 0; i < count; i++)
252130803Smarcel    {
253130803Smarcel      *hex++ = tohex ((*bin >> 4) & 0xf);
254130803Smarcel      *hex++ = tohex (*bin++ & 0xf);
255130803Smarcel    }
256130803Smarcel  *hex = 0;
257130803Smarcel  return i;
258130803Smarcel}
259130803Smarcel
26019370Spst/* Send a packet to the remote machine, with error checking.
26119370Spst   The data of the packet is in BUF.  Returns >= 0 on success, -1 otherwise. */
26219370Spst
26319370Spstint
26498944Sobrienputpkt (char *buf)
26519370Spst{
26619370Spst  int i;
26719370Spst  unsigned char csum = 0;
26898944Sobrien  char *buf2;
26919370Spst  char buf3[1];
27019370Spst  int cnt = strlen (buf);
27119370Spst  char *p;
27219370Spst
27398944Sobrien  buf2 = malloc (PBUFSIZ);
27498944Sobrien
27519370Spst  /* Copy the packet into buffer BUF2, encapsulating it
27619370Spst     and giving it a checksum.  */
27719370Spst
27819370Spst  p = buf2;
27919370Spst  *p++ = '$';
28019370Spst
28119370Spst  for (i = 0; i < cnt; i++)
28219370Spst    {
28319370Spst      csum += buf[i];
28419370Spst      *p++ = buf[i];
28519370Spst    }
28619370Spst  *p++ = '#';
28719370Spst  *p++ = tohex ((csum >> 4) & 0xf);
28819370Spst  *p++ = tohex (csum & 0xf);
28919370Spst
29046283Sdfr  *p = '\0';
29146283Sdfr
29219370Spst  /* Send it over and over until we get a positive ack.  */
29319370Spst
29419370Spst  do
29519370Spst    {
29619370Spst      int cc;
29719370Spst
29819370Spst      if (write (remote_desc, buf2, p - buf2) != p - buf2)
29919370Spst	{
30019370Spst	  perror ("putpkt(write)");
30119370Spst	  return -1;
30219370Spst	}
30319370Spst
30446283Sdfr      if (remote_debug)
305130803Smarcel	{
306130803Smarcel	  fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
307130803Smarcel	  fflush (stderr);
308130803Smarcel	}
30919370Spst      cc = read (remote_desc, buf3, 1);
31046283Sdfr      if (remote_debug)
311130803Smarcel	{
312130803Smarcel	  fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
313130803Smarcel	  fflush (stderr);
314130803Smarcel	}
315130803Smarcel
31619370Spst      if (cc <= 0)
31719370Spst	{
31819370Spst	  if (cc == 0)
31919370Spst	    fprintf (stderr, "putpkt(read): Got EOF\n");
32019370Spst	  else
32119370Spst	    perror ("putpkt(read)");
32219370Spst
32398944Sobrien	  free (buf2);
32419370Spst	  return -1;
32519370Spst	}
326130803Smarcel
327130803Smarcel      /* Check for an input interrupt while we're here.  */
328130803Smarcel      if (buf3[0] == '\003')
329130803Smarcel	(*the_target->send_signal) (SIGINT);
33019370Spst    }
33119370Spst  while (buf3[0] != '+');
33219370Spst
33398944Sobrien  free (buf2);
33419370Spst  return 1;			/* Success! */
33519370Spst}
33619370Spst
33719370Spst/* Come here when we get an input interrupt from the remote side.  This
33819370Spst   interrupt should only be active while we are waiting for the child to do
33919370Spst   something.  About the only thing that should come through is a ^C, which
34019370Spst   will cause us to send a SIGINT to the child.  */
34119370Spst
34219370Spststatic void
34398944Sobrieninput_interrupt (int unused)
34419370Spst{
34598944Sobrien  fd_set readset;
34698944Sobrien  struct timeval immediate = { 0, 0 };
34719370Spst
34898944Sobrien  /* Protect against spurious interrupts.  This has been observed to
34998944Sobrien     be a problem under NetBSD 1.4 and 1.5.  */
35019370Spst
35198944Sobrien  FD_ZERO (&readset);
35298944Sobrien  FD_SET (remote_desc, &readset);
35398944Sobrien  if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
35419370Spst    {
35598944Sobrien      int cc;
35698944Sobrien      char c;
35798944Sobrien
35898944Sobrien      cc = read (remote_desc, &c, 1);
35998944Sobrien
36098944Sobrien      if (cc != 1 || c != '\003')
36198944Sobrien	{
36298944Sobrien	  fprintf (stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
36398944Sobrien	  return;
36498944Sobrien	}
36598944Sobrien
366130803Smarcel      (*the_target->send_signal) (SIGINT);
36719370Spst    }
36819370Spst}
36919370Spst
37019370Spstvoid
371130803Smarcelblock_async_io (void)
372130803Smarcel{
373130803Smarcel  sigset_t sigio_set;
374130803Smarcel  sigemptyset (&sigio_set);
375130803Smarcel  sigaddset (&sigio_set, SIGIO);
376130803Smarcel  sigprocmask (SIG_BLOCK, &sigio_set, NULL);
377130803Smarcel}
378130803Smarcel
379130803Smarcelvoid
380130803Smarcelunblock_async_io (void)
381130803Smarcel{
382130803Smarcel  sigset_t sigio_set;
383130803Smarcel  sigemptyset (&sigio_set);
384130803Smarcel  sigaddset (&sigio_set, SIGIO);
385130803Smarcel  sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
386130803Smarcel}
387130803Smarcel
388130803Smarcelvoid
38998944Sobrienenable_async_io (void)
39019370Spst{
39119370Spst  signal (SIGIO, input_interrupt);
39219370Spst}
39319370Spst
39419370Spstvoid
39598944Sobriendisable_async_io (void)
39619370Spst{
39719370Spst  signal (SIGIO, SIG_IGN);
39819370Spst}
39919370Spst
40019370Spst/* Returns next char from remote GDB.  -1 if error.  */
40119370Spst
40219370Spststatic int
40398944Sobrienreadchar (void)
40419370Spst{
40519370Spst  static char buf[BUFSIZ];
40619370Spst  static int bufcnt = 0;
40719370Spst  static char *bufp;
40819370Spst
40919370Spst  if (bufcnt-- > 0)
41019370Spst    return *bufp++ & 0x7f;
41119370Spst
41219370Spst  bufcnt = read (remote_desc, buf, sizeof (buf));
41319370Spst
41419370Spst  if (bufcnt <= 0)
41519370Spst    {
41619370Spst      if (bufcnt == 0)
41719370Spst	fprintf (stderr, "readchar: Got EOF\n");
41819370Spst      else
41919370Spst	perror ("readchar");
42019370Spst
42119370Spst      return -1;
42219370Spst    }
42319370Spst
42419370Spst  bufp = buf;
42519370Spst  bufcnt--;
42619370Spst  return *bufp++ & 0x7f;
42719370Spst}
42819370Spst
42919370Spst/* Read a packet from the remote machine, with error checking,
43019370Spst   and store it in BUF.  Returns length of packet, or negative if error. */
43119370Spst
43219370Spstint
43398944Sobriengetpkt (char *buf)
43419370Spst{
43519370Spst  char *bp;
43619370Spst  unsigned char csum, c1, c2;
43719370Spst  int c;
43819370Spst
43919370Spst  while (1)
44019370Spst    {
44119370Spst      csum = 0;
44219370Spst
44319370Spst      while (1)
44419370Spst	{
44519370Spst	  c = readchar ();
44619370Spst	  if (c == '$')
44719370Spst	    break;
44846283Sdfr	  if (remote_debug)
449130803Smarcel	    {
450130803Smarcel	      fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
451130803Smarcel	      fflush (stderr);
452130803Smarcel	    }
453130803Smarcel
45419370Spst	  if (c < 0)
45519370Spst	    return -1;
45619370Spst	}
45719370Spst
45819370Spst      bp = buf;
45919370Spst      while (1)
46019370Spst	{
46119370Spst	  c = readchar ();
46219370Spst	  if (c < 0)
46319370Spst	    return -1;
46419370Spst	  if (c == '#')
46519370Spst	    break;
46619370Spst	  *bp++ = c;
46719370Spst	  csum += c;
46819370Spst	}
46919370Spst      *bp = 0;
47019370Spst
47119370Spst      c1 = fromhex (readchar ());
47219370Spst      c2 = fromhex (readchar ());
47398944Sobrien
47419370Spst      if (csum == (c1 << 4) + c2)
47519370Spst	break;
47619370Spst
47719370Spst      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
47819370Spst	       (c1 << 4) + c2, csum, buf);
47919370Spst      write (remote_desc, "-", 1);
48019370Spst    }
48119370Spst
48246283Sdfr  if (remote_debug)
483130803Smarcel    {
484130803Smarcel      fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
485130803Smarcel      fflush (stderr);
486130803Smarcel    }
48746283Sdfr
48819370Spst  write (remote_desc, "+", 1);
48946283Sdfr
49046283Sdfr  if (remote_debug)
491130803Smarcel    {
492130803Smarcel      fprintf (stderr, "[sent ack]\n");
493130803Smarcel      fflush (stderr);
494130803Smarcel    }
495130803Smarcel
49619370Spst  return bp - buf;
49719370Spst}
49819370Spst
49919370Spstvoid
50098944Sobrienwrite_ok (char *buf)
50119370Spst{
50219370Spst  buf[0] = 'O';
50319370Spst  buf[1] = 'K';
50419370Spst  buf[2] = '\0';
50519370Spst}
50619370Spst
50719370Spstvoid
50898944Sobrienwrite_enn (char *buf)
50919370Spst{
510130803Smarcel  /* Some day, we should define the meanings of the error codes... */
51119370Spst  buf[0] = 'E';
512130803Smarcel  buf[1] = '0';
513130803Smarcel  buf[2] = '1';
51419370Spst  buf[3] = '\0';
51519370Spst}
51619370Spst
51719370Spstvoid
51898944Sobrienconvert_int_to_ascii (char *from, char *to, int n)
51919370Spst{
52019370Spst  int nib;
52119370Spst  char ch;
52219370Spst  while (n--)
52319370Spst    {
52419370Spst      ch = *from++;
52519370Spst      nib = ((ch & 0xf0) >> 4) & 0x0f;
52619370Spst      *to++ = tohex (nib);
52719370Spst      nib = ch & 0x0f;
52819370Spst      *to++ = tohex (nib);
52919370Spst    }
53019370Spst  *to++ = 0;
53119370Spst}
53219370Spst
53319370Spst
53419370Spstvoid
53598944Sobrienconvert_ascii_to_int (char *from, char *to, int n)
53619370Spst{
53719370Spst  int nib1, nib2;
53819370Spst  while (n--)
53919370Spst    {
54019370Spst      nib1 = fromhex (*from++);
54119370Spst      nib2 = fromhex (*from++);
54219370Spst      *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
54319370Spst    }
54419370Spst}
54519370Spst
54619370Spststatic char *
54798944Sobrienoutreg (int regno, char *buf)
54819370Spst{
54998944Sobrien  if ((regno >> 12) != 0)
55098944Sobrien    *buf++ = tohex ((regno >> 12) & 0xf);
55198944Sobrien  if ((regno >> 8) != 0)
55298944Sobrien    *buf++ = tohex ((regno >> 8) & 0xf);
55398944Sobrien  *buf++ = tohex ((regno >> 4) & 0xf);
55419370Spst  *buf++ = tohex (regno & 0xf);
55519370Spst  *buf++ = ':';
556130803Smarcel  collect_register_as_string (regno, buf);
557130803Smarcel  buf += 2 * register_size (regno);
55819370Spst  *buf++ = ';';
55919370Spst
56019370Spst  return buf;
56119370Spst}
56219370Spst
56319370Spstvoid
564130803Smarcelnew_thread_notify (int id)
565130803Smarcel{
566130803Smarcel  char own_buf[256];
567130803Smarcel
568130803Smarcel  /* The `n' response is not yet part of the remote protocol.  Do nothing.  */
569130803Smarcel  if (1)
570130803Smarcel    return;
571130803Smarcel
572130803Smarcel  if (server_waiting == 0)
573130803Smarcel    return;
574130803Smarcel
575130803Smarcel  sprintf (own_buf, "n%x", id);
576130803Smarcel  disable_async_io ();
577130803Smarcel  putpkt (own_buf);
578130803Smarcel  enable_async_io ();
579130803Smarcel}
580130803Smarcel
581130803Smarcelvoid
582130803Smarceldead_thread_notify (int id)
583130803Smarcel{
584130803Smarcel  char own_buf[256];
585130803Smarcel
586130803Smarcel  /* The `x' response is not yet part of the remote protocol.  Do nothing.  */
587130803Smarcel  if (1)
588130803Smarcel    return;
589130803Smarcel
590130803Smarcel  sprintf (own_buf, "x%x", id);
591130803Smarcel  disable_async_io ();
592130803Smarcel  putpkt (own_buf);
593130803Smarcel  enable_async_io ();
594130803Smarcel}
595130803Smarcel
596130803Smarcelvoid
59798944Sobrienprepare_resume_reply (char *buf, char status, unsigned char signo)
59819370Spst{
59998944Sobrien  int nib, sig;
60019370Spst
60119370Spst  *buf++ = status;
60219370Spst
60398944Sobrien  sig = (int)target_signal_from_host (signo);
60498944Sobrien
60598944Sobrien  nib = ((sig & 0xf0) >> 4);
60619370Spst  *buf++ = tohex (nib);
60798944Sobrien  nib = sig & 0x0f;
60819370Spst  *buf++ = tohex (nib);
60919370Spst
61019370Spst  if (status == 'T')
61119370Spst    {
61298944Sobrien      const char **regp = gdbserver_expedite_regs;
61398944Sobrien      while (*regp)
61498944Sobrien	{
61598944Sobrien	  buf = outreg (find_regno (*regp), buf);
61698944Sobrien	  regp ++;
61798944Sobrien	}
61819370Spst
619130803Smarcel      /* Formerly, if the debugger had not used any thread features we would not
620130803Smarcel	 burden it with a thread status response.  This was for the benefit of
621130803Smarcel	 GDB 4.13 and older.  However, in recent GDB versions the check
622130803Smarcel	 (``if (cont_thread != 0)'') does not have the desired effect because of
623130803Smarcel	 sillyness in the way that the remote protocol handles specifying a thread.
624130803Smarcel	 Since thread support relies on qSymbol support anyway, assume GDB can handle
625130803Smarcel	 threads.  */
626130803Smarcel
627130803Smarcel      if (using_threads)
62819370Spst	{
629130803Smarcel	  /* FIXME right place to set this? */
630130803Smarcel	  thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
631130803Smarcel	  if (debug_threads)
632130803Smarcel	    fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait);
633130803Smarcel	  /* This if (1) ought to be unnecessary.  But remote_wait in GDB
634130803Smarcel	     will claim this event belongs to inferior_ptid if we do not
635130803Smarcel	     specify a thread, and there's no way for gdbserver to know
636130803Smarcel	     what inferior_ptid is.  */
637130803Smarcel	  if (1 || old_thread_from_wait != thread_from_wait)
63819370Spst	    {
639130803Smarcel	      general_thread = thread_from_wait;
64019370Spst	      sprintf (buf, "thread:%x;", thread_from_wait);
64119370Spst	      buf += strlen (buf);
64219370Spst	      old_thread_from_wait = thread_from_wait;
64319370Spst	    }
64419370Spst	}
64519370Spst    }
64619370Spst  /* For W and X, we're done.  */
64719370Spst  *buf++ = 0;
64819370Spst}
64919370Spst
65019370Spstvoid
65198944Sobriendecode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
65219370Spst{
65319370Spst  int i = 0, j = 0;
65419370Spst  char ch;
65519370Spst  *mem_addr_ptr = *len_ptr = 0;
65619370Spst
65719370Spst  while ((ch = from[i++]) != ',')
65819370Spst    {
65919370Spst      *mem_addr_ptr = *mem_addr_ptr << 4;
66019370Spst      *mem_addr_ptr |= fromhex (ch) & 0x0f;
66119370Spst    }
66219370Spst
66319370Spst  for (j = 0; j < 4; j++)
66419370Spst    {
66519370Spst      if ((ch = from[i++]) == 0)
66619370Spst	break;
66719370Spst      *len_ptr = *len_ptr << 4;
66819370Spst      *len_ptr |= fromhex (ch) & 0x0f;
66919370Spst    }
67019370Spst}
67119370Spst
67219370Spstvoid
67398944Sobriendecode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
67498944Sobrien		 char *to)
67519370Spst{
67646283Sdfr  int i = 0;
67719370Spst  char ch;
67819370Spst  *mem_addr_ptr = *len_ptr = 0;
67919370Spst
68019370Spst  while ((ch = from[i++]) != ',')
68119370Spst    {
68219370Spst      *mem_addr_ptr = *mem_addr_ptr << 4;
68319370Spst      *mem_addr_ptr |= fromhex (ch) & 0x0f;
68419370Spst    }
68519370Spst
68619370Spst  while ((ch = from[i++]) != ':')
68719370Spst    {
68819370Spst      *len_ptr = *len_ptr << 4;
68919370Spst      *len_ptr |= fromhex (ch) & 0x0f;
69019370Spst    }
69119370Spst
69219370Spst  convert_ascii_to_int (&from[i++], to, *len_ptr);
69319370Spst}
694130803Smarcel
695130803Smarcelint
696130803Smarcellook_up_one_symbol (const char *name, CORE_ADDR *addrp)
697130803Smarcel{
698130803Smarcel  char own_buf[266], *p, *q;
699130803Smarcel  int len;
700130803Smarcel
701130803Smarcel  /* Send the request.  */
702130803Smarcel  strcpy (own_buf, "qSymbol:");
703130803Smarcel  hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
704130803Smarcel  if (putpkt (own_buf) < 0)
705130803Smarcel    return -1;
706130803Smarcel
707130803Smarcel  /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
708130803Smarcel  len = getpkt (own_buf);
709130803Smarcel  if (len < 0)
710130803Smarcel    return -1;
711130803Smarcel
712130803Smarcel  if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
713130803Smarcel    {
714130803Smarcel      /* Malformed response.  */
715130803Smarcel      if (remote_debug)
716130803Smarcel	{
717130803Smarcel	  fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
718130803Smarcel	  fflush (stderr);
719130803Smarcel	}
720130803Smarcel
721130803Smarcel      return -1;
722130803Smarcel    }
723130803Smarcel
724130803Smarcel  p = own_buf + strlen ("qSymbol:");
725130803Smarcel  q = p;
726130803Smarcel  while (*q && *q != ':')
727130803Smarcel    q++;
728130803Smarcel
729130803Smarcel  /* Make sure we found a value for the symbol.  */
730130803Smarcel  if (p == q || *q == '\0')
731130803Smarcel    return 0;
732130803Smarcel
733130803Smarcel  decode_address (addrp, p, q - p);
734130803Smarcel  return 1;
735130803Smarcel}
736130803Smarcel
737