xref: /openbsd-src/gnu/usr.bin/binutils/gdb/gdbserver/remote-utils.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1e93f7393Sniklas /* Remote utility routines for the remote server for GDB.
2b725ae77Skettenis    Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3b725ae77Skettenis    2002, 2003, 2004
4b725ae77Skettenis    Free Software Foundation, Inc.
5e93f7393Sniklas 
6e93f7393Sniklas    This file is part of GDB.
7e93f7393Sniklas 
8e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
9e93f7393Sniklas    it under the terms of the GNU General Public License as published by
10e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
11e93f7393Sniklas    (at your option) any later version.
12e93f7393Sniklas 
13e93f7393Sniklas    This program is distributed in the hope that it will be useful,
14e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
15e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e93f7393Sniklas    GNU General Public License for more details.
17e93f7393Sniklas 
18e93f7393Sniklas    You should have received a copy of the GNU General Public License
19e93f7393Sniklas    along with this program; if not, write to the Free Software
20b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
22e93f7393Sniklas 
23e93f7393Sniklas #include "server.h"
24b725ae77Skettenis #include "terminal.h"
25e93f7393Sniklas #include <stdio.h>
26b725ae77Skettenis #include <string.h>
27e93f7393Sniklas #include <sys/ioctl.h>
28e93f7393Sniklas #include <sys/file.h>
29e93f7393Sniklas #include <netinet/in.h>
30e93f7393Sniklas #include <sys/socket.h>
31e93f7393Sniklas #include <netdb.h>
32e93f7393Sniklas #include <netinet/tcp.h>
33e93f7393Sniklas #include <sys/ioctl.h>
34e93f7393Sniklas #include <signal.h>
35b725ae77Skettenis #include <fcntl.h>
36b725ae77Skettenis #include <sys/time.h>
37b725ae77Skettenis #include <unistd.h>
38b725ae77Skettenis #include <arpa/inet.h>
39e93f7393Sniklas 
40*63addd46Skettenis /* A cache entry for a successfully looked-up symbol.  */
41*63addd46Skettenis struct sym_cache
42*63addd46Skettenis {
43*63addd46Skettenis   const char *name;
44*63addd46Skettenis   CORE_ADDR addr;
45*63addd46Skettenis   struct sym_cache *next;
46*63addd46Skettenis };
47*63addd46Skettenis 
48*63addd46Skettenis /* The symbol cache.  */
49*63addd46Skettenis static struct sym_cache *symbol_cache;
50*63addd46Skettenis 
51b725ae77Skettenis int remote_debug = 0;
52b725ae77Skettenis struct ui_file *gdb_stdlog;
53b725ae77Skettenis 
54e93f7393Sniklas static int remote_desc;
55e93f7393Sniklas 
56b725ae77Skettenis /* FIXME headerize? */
57b725ae77Skettenis extern int using_threads;
58b725ae77Skettenis extern int debug_threads;
59b725ae77Skettenis 
60e93f7393Sniklas /* Open a connection to a remote debugger.
61e93f7393Sniklas    NAME is the filename used for communication.  */
62e93f7393Sniklas 
63e93f7393Sniklas void
remote_open(char * name)64b725ae77Skettenis remote_open (char *name)
65e93f7393Sniklas {
66b725ae77Skettenis   int save_fcntl_flags;
67b725ae77Skettenis 
68e93f7393Sniklas   if (!strchr (name, ':'))
69e93f7393Sniklas     {
70e93f7393Sniklas       remote_desc = open (name, O_RDWR);
71e93f7393Sniklas       if (remote_desc < 0)
72e93f7393Sniklas 	perror_with_name ("Could not open remote device");
73e93f7393Sniklas 
74e93f7393Sniklas #ifdef HAVE_TERMIOS
75e93f7393Sniklas       {
76e93f7393Sniklas 	struct termios termios;
77e93f7393Sniklas 	tcgetattr (remote_desc, &termios);
78e93f7393Sniklas 
79e93f7393Sniklas 	termios.c_iflag = 0;
80e93f7393Sniklas 	termios.c_oflag = 0;
81e93f7393Sniklas 	termios.c_lflag = 0;
82e93f7393Sniklas 	termios.c_cflag &= ~(CSIZE | PARENB);
83e93f7393Sniklas 	termios.c_cflag |= CLOCAL | CS8;
84b725ae77Skettenis 	termios.c_cc[VMIN] = 1;
85e93f7393Sniklas 	termios.c_cc[VTIME] = 0;
86e93f7393Sniklas 
87e93f7393Sniklas 	tcsetattr (remote_desc, TCSANOW, &termios);
88e93f7393Sniklas       }
89e93f7393Sniklas #endif
90e93f7393Sniklas 
91e93f7393Sniklas #ifdef HAVE_TERMIO
92e93f7393Sniklas       {
93e93f7393Sniklas 	struct termio termio;
94e93f7393Sniklas 	ioctl (remote_desc, TCGETA, &termio);
95e93f7393Sniklas 
96e93f7393Sniklas 	termio.c_iflag = 0;
97e93f7393Sniklas 	termio.c_oflag = 0;
98e93f7393Sniklas 	termio.c_lflag = 0;
99e93f7393Sniklas 	termio.c_cflag &= ~(CSIZE | PARENB);
100e93f7393Sniklas 	termio.c_cflag |= CLOCAL | CS8;
101b725ae77Skettenis 	termio.c_cc[VMIN] = 1;
102e93f7393Sniklas 	termio.c_cc[VTIME] = 0;
103e93f7393Sniklas 
104e93f7393Sniklas 	ioctl (remote_desc, TCSETA, &termio);
105e93f7393Sniklas       }
106e93f7393Sniklas #endif
107e93f7393Sniklas 
108e93f7393Sniklas #ifdef HAVE_SGTTY
109e93f7393Sniklas       {
110e93f7393Sniklas 	struct sgttyb sg;
111e93f7393Sniklas 
112e93f7393Sniklas 	ioctl (remote_desc, TIOCGETP, &sg);
113e93f7393Sniklas 	sg.sg_flags = RAW;
114e93f7393Sniklas 	ioctl (remote_desc, TIOCSETP, &sg);
115e93f7393Sniklas       }
116e93f7393Sniklas #endif
117e93f7393Sniklas 
118b725ae77Skettenis       fprintf (stderr, "Remote debugging using %s\n", name);
119e93f7393Sniklas     }
120e93f7393Sniklas   else
121e93f7393Sniklas     {
122e93f7393Sniklas       char *port_str;
123e93f7393Sniklas       int port;
124e93f7393Sniklas       struct sockaddr_in sockaddr;
125e93f7393Sniklas       int tmp;
126e93f7393Sniklas       int tmp_desc;
127e93f7393Sniklas 
128e93f7393Sniklas       port_str = strchr (name, ':');
129e93f7393Sniklas 
130e93f7393Sniklas       port = atoi (port_str + 1);
131e93f7393Sniklas 
132e93f7393Sniklas       tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
133e93f7393Sniklas       if (tmp_desc < 0)
134e93f7393Sniklas 	perror_with_name ("Can't open socket");
135e93f7393Sniklas 
136e93f7393Sniklas       /* Allow rapid reuse of this port. */
137e93f7393Sniklas       tmp = 1;
138e93f7393Sniklas       setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
139e93f7393Sniklas 		  sizeof (tmp));
140e93f7393Sniklas 
141e93f7393Sniklas       sockaddr.sin_family = PF_INET;
142e93f7393Sniklas       sockaddr.sin_port = htons (port);
143e93f7393Sniklas       sockaddr.sin_addr.s_addr = INADDR_ANY;
144e93f7393Sniklas 
145e93f7393Sniklas       if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
146e93f7393Sniklas 	  || listen (tmp_desc, 1))
147e93f7393Sniklas 	perror_with_name ("Can't bind address");
148e93f7393Sniklas 
149b725ae77Skettenis       fprintf (stderr, "Listening on port %d\n", port);
150b725ae77Skettenis 
151e93f7393Sniklas       tmp = sizeof (sockaddr);
152e93f7393Sniklas       remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
153e93f7393Sniklas       if (remote_desc == -1)
154e93f7393Sniklas 	perror_with_name ("Accept failed");
155e93f7393Sniklas 
156e93f7393Sniklas       /* Enable TCP keep alive process. */
157e93f7393Sniklas       tmp = 1;
158e93f7393Sniklas       setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
159e93f7393Sniklas 
160e93f7393Sniklas       /* Tell TCP not to delay small packets.  This greatly speeds up
161e93f7393Sniklas          interactive response. */
162e93f7393Sniklas       tmp = 1;
163b725ae77Skettenis       setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
164e93f7393Sniklas 		  (char *) &tmp, sizeof (tmp));
165e93f7393Sniklas 
166e93f7393Sniklas       close (tmp_desc);		/* No longer need this */
167e93f7393Sniklas 
168e93f7393Sniklas       signal (SIGPIPE, SIG_IGN);	/* If we don't do this, then gdbserver simply
169e93f7393Sniklas 					   exits when the remote side dies.  */
170b725ae77Skettenis 
171b725ae77Skettenis       /* Convert IP address to string.  */
172b725ae77Skettenis       fprintf (stderr, "Remote debugging from host %s\n",
173b725ae77Skettenis          inet_ntoa (sockaddr.sin_addr));
174e93f7393Sniklas     }
175e93f7393Sniklas 
176b725ae77Skettenis #if defined(F_SETFL) && defined (FASYNC)
177b725ae77Skettenis   save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
178b725ae77Skettenis   fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
179b725ae77Skettenis #if defined (F_SETOWN)
180b725ae77Skettenis   fcntl (remote_desc, F_SETOWN, getpid ());
181b725ae77Skettenis #endif
182b725ae77Skettenis #endif
183b725ae77Skettenis   disable_async_io ();
184e93f7393Sniklas }
185e93f7393Sniklas 
186e93f7393Sniklas void
remote_close(void)187b725ae77Skettenis remote_close (void)
188e93f7393Sniklas {
189e93f7393Sniklas   close (remote_desc);
190e93f7393Sniklas }
191e93f7393Sniklas 
192e93f7393Sniklas /* Convert hex digit A to a number.  */
193e93f7393Sniklas 
194e93f7393Sniklas static int
fromhex(int a)195b725ae77Skettenis fromhex (int a)
196e93f7393Sniklas {
197e93f7393Sniklas   if (a >= '0' && a <= '9')
198e93f7393Sniklas     return a - '0';
199e93f7393Sniklas   else if (a >= 'a' && a <= 'f')
200e93f7393Sniklas     return a - 'a' + 10;
201e93f7393Sniklas   else
202e93f7393Sniklas     error ("Reply contains invalid hex digit");
203b725ae77Skettenis   return 0;
204b725ae77Skettenis }
205b725ae77Skettenis 
206b725ae77Skettenis int
unhexify(char * bin,const char * hex,int count)207b725ae77Skettenis unhexify (char *bin, const char *hex, int count)
208b725ae77Skettenis {
209b725ae77Skettenis   int i;
210b725ae77Skettenis 
211b725ae77Skettenis   for (i = 0; i < count; i++)
212b725ae77Skettenis     {
213b725ae77Skettenis       if (hex[0] == 0 || hex[1] == 0)
214b725ae77Skettenis         {
215b725ae77Skettenis           /* Hex string is short, or of uneven length.
216b725ae77Skettenis              Return the count that has been converted so far. */
217b725ae77Skettenis           return i;
218b725ae77Skettenis         }
219b725ae77Skettenis       *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
220b725ae77Skettenis       hex += 2;
221b725ae77Skettenis     }
222b725ae77Skettenis   return i;
223b725ae77Skettenis }
224b725ae77Skettenis 
225b725ae77Skettenis static void
decode_address(CORE_ADDR * addrp,const char * start,int len)226b725ae77Skettenis decode_address (CORE_ADDR *addrp, const char *start, int len)
227b725ae77Skettenis {
228b725ae77Skettenis   CORE_ADDR addr;
229b725ae77Skettenis   char ch;
230b725ae77Skettenis   int i;
231b725ae77Skettenis 
232b725ae77Skettenis   addr = 0;
233b725ae77Skettenis   for (i = 0; i < len; i++)
234b725ae77Skettenis     {
235b725ae77Skettenis       ch = start[i];
236b725ae77Skettenis       addr = addr << 4;
237b725ae77Skettenis       addr = addr | (fromhex (ch) & 0x0f);
238b725ae77Skettenis     }
239b725ae77Skettenis   *addrp = addr;
240e93f7393Sniklas }
241e93f7393Sniklas 
242e93f7393Sniklas /* Convert number NIB to a hex digit.  */
243e93f7393Sniklas 
244e93f7393Sniklas static int
tohex(int nib)245b725ae77Skettenis tohex (int nib)
246e93f7393Sniklas {
247e93f7393Sniklas   if (nib < 10)
248e93f7393Sniklas     return '0' + nib;
249e93f7393Sniklas   else
250e93f7393Sniklas     return 'a' + nib - 10;
251e93f7393Sniklas }
252e93f7393Sniklas 
253b725ae77Skettenis int
hexify(char * hex,const char * bin,int count)254b725ae77Skettenis hexify (char *hex, const char *bin, int count)
255b725ae77Skettenis {
256b725ae77Skettenis   int i;
257b725ae77Skettenis 
258b725ae77Skettenis   /* May use a length, or a nul-terminated string as input. */
259b725ae77Skettenis   if (count == 0)
260b725ae77Skettenis     count = strlen (bin);
261b725ae77Skettenis 
262b725ae77Skettenis   for (i = 0; i < count; i++)
263b725ae77Skettenis     {
264b725ae77Skettenis       *hex++ = tohex ((*bin >> 4) & 0xf);
265b725ae77Skettenis       *hex++ = tohex (*bin++ & 0xf);
266b725ae77Skettenis     }
267b725ae77Skettenis   *hex = 0;
268b725ae77Skettenis   return i;
269b725ae77Skettenis }
270b725ae77Skettenis 
271e93f7393Sniklas /* Send a packet to the remote machine, with error checking.
272e93f7393Sniklas    The data of the packet is in BUF.  Returns >= 0 on success, -1 otherwise. */
273e93f7393Sniklas 
274e93f7393Sniklas int
putpkt(char * buf)275b725ae77Skettenis putpkt (char *buf)
276e93f7393Sniklas {
277e93f7393Sniklas   int i;
278e93f7393Sniklas   unsigned char csum = 0;
279b725ae77Skettenis   char *buf2;
280e93f7393Sniklas   char buf3[1];
281e93f7393Sniklas   int cnt = strlen (buf);
282e93f7393Sniklas   char *p;
283e93f7393Sniklas 
284b725ae77Skettenis   buf2 = malloc (PBUFSIZ);
285b725ae77Skettenis 
286e93f7393Sniklas   /* Copy the packet into buffer BUF2, encapsulating it
287e93f7393Sniklas      and giving it a checksum.  */
288e93f7393Sniklas 
289e93f7393Sniklas   p = buf2;
290e93f7393Sniklas   *p++ = '$';
291e93f7393Sniklas 
292e93f7393Sniklas   for (i = 0; i < cnt; i++)
293e93f7393Sniklas     {
294e93f7393Sniklas       csum += buf[i];
295e93f7393Sniklas       *p++ = buf[i];
296e93f7393Sniklas     }
297e93f7393Sniklas   *p++ = '#';
298e93f7393Sniklas   *p++ = tohex ((csum >> 4) & 0xf);
299e93f7393Sniklas   *p++ = tohex (csum & 0xf);
300e93f7393Sniklas 
301b725ae77Skettenis   *p = '\0';
302b725ae77Skettenis 
303e93f7393Sniklas   /* Send it over and over until we get a positive ack.  */
304e93f7393Sniklas 
305e93f7393Sniklas   do
306e93f7393Sniklas     {
307e93f7393Sniklas       int cc;
308e93f7393Sniklas 
309e93f7393Sniklas       if (write (remote_desc, buf2, p - buf2) != p - buf2)
310e93f7393Sniklas 	{
311e93f7393Sniklas 	  perror ("putpkt(write)");
312e93f7393Sniklas 	  return -1;
313e93f7393Sniklas 	}
314e93f7393Sniklas 
315b725ae77Skettenis       if (remote_debug)
316b725ae77Skettenis 	{
317b725ae77Skettenis 	  fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
318b725ae77Skettenis 	  fflush (stderr);
319b725ae77Skettenis 	}
320e93f7393Sniklas       cc = read (remote_desc, buf3, 1);
321b725ae77Skettenis       if (remote_debug)
322b725ae77Skettenis 	{
323b725ae77Skettenis 	  fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
324b725ae77Skettenis 	  fflush (stderr);
325b725ae77Skettenis 	}
326b725ae77Skettenis 
327e93f7393Sniklas       if (cc <= 0)
328e93f7393Sniklas 	{
329e93f7393Sniklas 	  if (cc == 0)
330e93f7393Sniklas 	    fprintf (stderr, "putpkt(read): Got EOF\n");
331e93f7393Sniklas 	  else
332e93f7393Sniklas 	    perror ("putpkt(read)");
333e93f7393Sniklas 
334b725ae77Skettenis 	  free (buf2);
335e93f7393Sniklas 	  return -1;
336e93f7393Sniklas 	}
337b725ae77Skettenis 
338b725ae77Skettenis       /* Check for an input interrupt while we're here.  */
339b725ae77Skettenis       if (buf3[0] == '\003')
340b725ae77Skettenis 	(*the_target->send_signal) (SIGINT);
341e93f7393Sniklas     }
342e93f7393Sniklas   while (buf3[0] != '+');
343e93f7393Sniklas 
344b725ae77Skettenis   free (buf2);
345e93f7393Sniklas   return 1;			/* Success! */
346e93f7393Sniklas }
347e93f7393Sniklas 
348e93f7393Sniklas /* Come here when we get an input interrupt from the remote side.  This
349e93f7393Sniklas    interrupt should only be active while we are waiting for the child to do
350e93f7393Sniklas    something.  About the only thing that should come through is a ^C, which
351e93f7393Sniklas    will cause us to send a SIGINT to the child.  */
352e93f7393Sniklas 
353e93f7393Sniklas static void
input_interrupt(int unused)354b725ae77Skettenis input_interrupt (int unused)
355b725ae77Skettenis {
356b725ae77Skettenis   fd_set readset;
357b725ae77Skettenis   struct timeval immediate = { 0, 0 };
358b725ae77Skettenis 
359b725ae77Skettenis   /* Protect against spurious interrupts.  This has been observed to
360b725ae77Skettenis      be a problem under NetBSD 1.4 and 1.5.  */
361b725ae77Skettenis 
362b725ae77Skettenis   FD_ZERO (&readset);
363b725ae77Skettenis   FD_SET (remote_desc, &readset);
364b725ae77Skettenis   if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
365e93f7393Sniklas     {
366e93f7393Sniklas       int cc;
367*63addd46Skettenis       char c = 0;
368e93f7393Sniklas 
369e93f7393Sniklas       cc = read (remote_desc, &c, 1);
370e93f7393Sniklas 
371e93f7393Sniklas       if (cc != 1 || c != '\003')
372e93f7393Sniklas 	{
373*63addd46Skettenis 	  fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
374*63addd46Skettenis 		   cc, c, c);
375e93f7393Sniklas 	  return;
376e93f7393Sniklas 	}
377e93f7393Sniklas 
378b725ae77Skettenis       (*the_target->send_signal) (SIGINT);
379b725ae77Skettenis     }
380e93f7393Sniklas }
381e93f7393Sniklas 
382e93f7393Sniklas void
block_async_io(void)383b725ae77Skettenis block_async_io (void)
384b725ae77Skettenis {
385b725ae77Skettenis   sigset_t sigio_set;
386b725ae77Skettenis   sigemptyset (&sigio_set);
387b725ae77Skettenis   sigaddset (&sigio_set, SIGIO);
388b725ae77Skettenis   sigprocmask (SIG_BLOCK, &sigio_set, NULL);
389b725ae77Skettenis }
390b725ae77Skettenis 
391b725ae77Skettenis void
unblock_async_io(void)392b725ae77Skettenis unblock_async_io (void)
393b725ae77Skettenis {
394b725ae77Skettenis   sigset_t sigio_set;
395b725ae77Skettenis   sigemptyset (&sigio_set);
396b725ae77Skettenis   sigaddset (&sigio_set, SIGIO);
397b725ae77Skettenis   sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
398b725ae77Skettenis }
399b725ae77Skettenis 
400*63addd46Skettenis /* Asynchronous I/O support.  SIGIO must be enabled when waiting, in order to
401*63addd46Skettenis    accept Control-C from the client, and must be disabled when talking to
402*63addd46Skettenis    the client.  */
403*63addd46Skettenis 
404*63addd46Skettenis /* Current state of asynchronous I/O.  */
405*63addd46Skettenis static int async_io_enabled;
406*63addd46Skettenis 
407*63addd46Skettenis /* Enable asynchronous I/O.  */
408b725ae77Skettenis void
enable_async_io(void)409b725ae77Skettenis enable_async_io (void)
410e93f7393Sniklas {
411*63addd46Skettenis   if (async_io_enabled)
412*63addd46Skettenis     return;
413*63addd46Skettenis 
414e93f7393Sniklas   signal (SIGIO, input_interrupt);
415*63addd46Skettenis   async_io_enabled = 1;
416e93f7393Sniklas }
417e93f7393Sniklas 
418*63addd46Skettenis /* Disable asynchronous I/O.  */
419e93f7393Sniklas void
disable_async_io(void)420b725ae77Skettenis disable_async_io (void)
421e93f7393Sniklas {
422*63addd46Skettenis   if (!async_io_enabled)
423*63addd46Skettenis     return;
424*63addd46Skettenis 
425e93f7393Sniklas   signal (SIGIO, SIG_IGN);
426*63addd46Skettenis   async_io_enabled = 0;
427e93f7393Sniklas }
428e93f7393Sniklas 
429e93f7393Sniklas /* Returns next char from remote GDB.  -1 if error.  */
430e93f7393Sniklas 
431e93f7393Sniklas static int
readchar(void)432b725ae77Skettenis readchar (void)
433e93f7393Sniklas {
434e93f7393Sniklas   static char buf[BUFSIZ];
435e93f7393Sniklas   static int bufcnt = 0;
436e93f7393Sniklas   static char *bufp;
437e93f7393Sniklas 
438e93f7393Sniklas   if (bufcnt-- > 0)
439e93f7393Sniklas     return *bufp++ & 0x7f;
440e93f7393Sniklas 
441e93f7393Sniklas   bufcnt = read (remote_desc, buf, sizeof (buf));
442e93f7393Sniklas 
443e93f7393Sniklas   if (bufcnt <= 0)
444e93f7393Sniklas     {
445e93f7393Sniklas       if (bufcnt == 0)
446e93f7393Sniklas 	fprintf (stderr, "readchar: Got EOF\n");
447e93f7393Sniklas       else
448e93f7393Sniklas 	perror ("readchar");
449e93f7393Sniklas 
450e93f7393Sniklas       return -1;
451e93f7393Sniklas     }
452e93f7393Sniklas 
453e93f7393Sniklas   bufp = buf;
454e93f7393Sniklas   bufcnt--;
455e93f7393Sniklas   return *bufp++ & 0x7f;
456e93f7393Sniklas }
457e93f7393Sniklas 
458e93f7393Sniklas /* Read a packet from the remote machine, with error checking,
459e93f7393Sniklas    and store it in BUF.  Returns length of packet, or negative if error. */
460e93f7393Sniklas 
461e93f7393Sniklas int
getpkt(char * buf)462b725ae77Skettenis getpkt (char *buf)
463e93f7393Sniklas {
464e93f7393Sniklas   char *bp;
465e93f7393Sniklas   unsigned char csum, c1, c2;
466e93f7393Sniklas   int c;
467e93f7393Sniklas 
468e93f7393Sniklas   while (1)
469e93f7393Sniklas     {
470e93f7393Sniklas       csum = 0;
471e93f7393Sniklas 
472e93f7393Sniklas       while (1)
473e93f7393Sniklas 	{
474e93f7393Sniklas 	  c = readchar ();
475e93f7393Sniklas 	  if (c == '$')
476e93f7393Sniklas 	    break;
477b725ae77Skettenis 	  if (remote_debug)
478b725ae77Skettenis 	    {
479b725ae77Skettenis 	      fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
480b725ae77Skettenis 	      fflush (stderr);
481b725ae77Skettenis 	    }
482b725ae77Skettenis 
483e93f7393Sniklas 	  if (c < 0)
484e93f7393Sniklas 	    return -1;
485e93f7393Sniklas 	}
486e93f7393Sniklas 
487e93f7393Sniklas       bp = buf;
488e93f7393Sniklas       while (1)
489e93f7393Sniklas 	{
490e93f7393Sniklas 	  c = readchar ();
491e93f7393Sniklas 	  if (c < 0)
492e93f7393Sniklas 	    return -1;
493e93f7393Sniklas 	  if (c == '#')
494e93f7393Sniklas 	    break;
495e93f7393Sniklas 	  *bp++ = c;
496e93f7393Sniklas 	  csum += c;
497e93f7393Sniklas 	}
498e93f7393Sniklas       *bp = 0;
499e93f7393Sniklas 
500e93f7393Sniklas       c1 = fromhex (readchar ());
501e93f7393Sniklas       c2 = fromhex (readchar ());
502b725ae77Skettenis 
503e93f7393Sniklas       if (csum == (c1 << 4) + c2)
504e93f7393Sniklas 	break;
505e93f7393Sniklas 
506e93f7393Sniklas       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
507e93f7393Sniklas 	       (c1 << 4) + c2, csum, buf);
508e93f7393Sniklas       write (remote_desc, "-", 1);
509e93f7393Sniklas     }
510e93f7393Sniklas 
511b725ae77Skettenis   if (remote_debug)
512b725ae77Skettenis     {
513b725ae77Skettenis       fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
514b725ae77Skettenis       fflush (stderr);
515b725ae77Skettenis     }
516b725ae77Skettenis 
517e93f7393Sniklas   write (remote_desc, "+", 1);
518b725ae77Skettenis 
519b725ae77Skettenis   if (remote_debug)
520b725ae77Skettenis     {
521b725ae77Skettenis       fprintf (stderr, "[sent ack]\n");
522b725ae77Skettenis       fflush (stderr);
523b725ae77Skettenis     }
524b725ae77Skettenis 
525e93f7393Sniklas   return bp - buf;
526e93f7393Sniklas }
527e93f7393Sniklas 
528e93f7393Sniklas void
write_ok(char * buf)529b725ae77Skettenis write_ok (char *buf)
530e93f7393Sniklas {
531e93f7393Sniklas   buf[0] = 'O';
532e93f7393Sniklas   buf[1] = 'K';
533e93f7393Sniklas   buf[2] = '\0';
534e93f7393Sniklas }
535e93f7393Sniklas 
536e93f7393Sniklas void
write_enn(char * buf)537b725ae77Skettenis write_enn (char *buf)
538e93f7393Sniklas {
539b725ae77Skettenis   /* Some day, we should define the meanings of the error codes... */
540e93f7393Sniklas   buf[0] = 'E';
541b725ae77Skettenis   buf[1] = '0';
542b725ae77Skettenis   buf[2] = '1';
543e93f7393Sniklas   buf[3] = '\0';
544e93f7393Sniklas }
545e93f7393Sniklas 
546e93f7393Sniklas void
convert_int_to_ascii(char * from,char * to,int n)547b725ae77Skettenis convert_int_to_ascii (char *from, char *to, int n)
548e93f7393Sniklas {
549e93f7393Sniklas   int nib;
550e93f7393Sniklas   char ch;
551e93f7393Sniklas   while (n--)
552e93f7393Sniklas     {
553e93f7393Sniklas       ch = *from++;
554e93f7393Sniklas       nib = ((ch & 0xf0) >> 4) & 0x0f;
555e93f7393Sniklas       *to++ = tohex (nib);
556e93f7393Sniklas       nib = ch & 0x0f;
557e93f7393Sniklas       *to++ = tohex (nib);
558e93f7393Sniklas     }
559e93f7393Sniklas   *to++ = 0;
560e93f7393Sniklas }
561e93f7393Sniklas 
562e93f7393Sniklas 
563e93f7393Sniklas void
convert_ascii_to_int(char * from,char * to,int n)564b725ae77Skettenis convert_ascii_to_int (char *from, char *to, int n)
565e93f7393Sniklas {
566e93f7393Sniklas   int nib1, nib2;
567e93f7393Sniklas   while (n--)
568e93f7393Sniklas     {
569e93f7393Sniklas       nib1 = fromhex (*from++);
570e93f7393Sniklas       nib2 = fromhex (*from++);
571e93f7393Sniklas       *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
572e93f7393Sniklas     }
573e93f7393Sniklas }
574e93f7393Sniklas 
575e93f7393Sniklas static char *
outreg(int regno,char * buf)576b725ae77Skettenis outreg (int regno, char *buf)
577e93f7393Sniklas {
578b725ae77Skettenis   if ((regno >> 12) != 0)
579b725ae77Skettenis     *buf++ = tohex ((regno >> 12) & 0xf);
580b725ae77Skettenis   if ((regno >> 8) != 0)
581b725ae77Skettenis     *buf++ = tohex ((regno >> 8) & 0xf);
582b725ae77Skettenis   *buf++ = tohex ((regno >> 4) & 0xf);
583e93f7393Sniklas   *buf++ = tohex (regno & 0xf);
584e93f7393Sniklas   *buf++ = ':';
585b725ae77Skettenis   collect_register_as_string (regno, buf);
586b725ae77Skettenis   buf += 2 * register_size (regno);
587e93f7393Sniklas   *buf++ = ';';
588e93f7393Sniklas 
589e93f7393Sniklas   return buf;
590e93f7393Sniklas }
591e93f7393Sniklas 
592e93f7393Sniklas void
new_thread_notify(int id)593b725ae77Skettenis new_thread_notify (int id)
594e93f7393Sniklas {
595b725ae77Skettenis   char own_buf[256];
596b725ae77Skettenis 
597b725ae77Skettenis   /* The `n' response is not yet part of the remote protocol.  Do nothing.  */
598b725ae77Skettenis   if (1)
599b725ae77Skettenis     return;
600b725ae77Skettenis 
601b725ae77Skettenis   if (server_waiting == 0)
602b725ae77Skettenis     return;
603b725ae77Skettenis 
604b725ae77Skettenis   sprintf (own_buf, "n%x", id);
605b725ae77Skettenis   disable_async_io ();
606b725ae77Skettenis   putpkt (own_buf);
607b725ae77Skettenis   enable_async_io ();
608b725ae77Skettenis }
609b725ae77Skettenis 
610b725ae77Skettenis void
dead_thread_notify(int id)611b725ae77Skettenis dead_thread_notify (int id)
612b725ae77Skettenis {
613b725ae77Skettenis   char own_buf[256];
614b725ae77Skettenis 
615b725ae77Skettenis   /* The `x' response is not yet part of the remote protocol.  Do nothing.  */
616b725ae77Skettenis   if (1)
617b725ae77Skettenis     return;
618b725ae77Skettenis 
619b725ae77Skettenis   sprintf (own_buf, "x%x", id);
620b725ae77Skettenis   disable_async_io ();
621b725ae77Skettenis   putpkt (own_buf);
622b725ae77Skettenis   enable_async_io ();
623b725ae77Skettenis }
624b725ae77Skettenis 
625b725ae77Skettenis void
prepare_resume_reply(char * buf,char status,unsigned char signo)626b725ae77Skettenis prepare_resume_reply (char *buf, char status, unsigned char signo)
627b725ae77Skettenis {
628b725ae77Skettenis   int nib, sig;
629e93f7393Sniklas 
630e93f7393Sniklas   *buf++ = status;
631e93f7393Sniklas 
632b725ae77Skettenis   sig = (int)target_signal_from_host (signo);
633b725ae77Skettenis 
634b725ae77Skettenis   nib = ((sig & 0xf0) >> 4);
635e93f7393Sniklas   *buf++ = tohex (nib);
636b725ae77Skettenis   nib = sig & 0x0f;
637e93f7393Sniklas   *buf++ = tohex (nib);
638e93f7393Sniklas 
639e93f7393Sniklas   if (status == 'T')
640e93f7393Sniklas     {
641b725ae77Skettenis       const char **regp = gdbserver_expedite_regs;
642b725ae77Skettenis       while (*regp)
643b725ae77Skettenis 	{
644b725ae77Skettenis 	  buf = outreg (find_regno (*regp), buf);
645b725ae77Skettenis 	  regp ++;
646b725ae77Skettenis 	}
647e93f7393Sniklas 
648b725ae77Skettenis       /* Formerly, if the debugger had not used any thread features we would not
649b725ae77Skettenis 	 burden it with a thread status response.  This was for the benefit of
650b725ae77Skettenis 	 GDB 4.13 and older.  However, in recent GDB versions the check
651b725ae77Skettenis 	 (``if (cont_thread != 0)'') does not have the desired effect because of
652b725ae77Skettenis 	 sillyness in the way that the remote protocol handles specifying a thread.
653b725ae77Skettenis 	 Since thread support relies on qSymbol support anyway, assume GDB can handle
654b725ae77Skettenis 	 threads.  */
655b725ae77Skettenis 
656b725ae77Skettenis       if (using_threads)
657e93f7393Sniklas 	{
658b725ae77Skettenis 	  /* FIXME right place to set this? */
659b725ae77Skettenis 	  thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
660b725ae77Skettenis 	  if (debug_threads)
661b725ae77Skettenis 	    fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait);
662b725ae77Skettenis 	  /* This if (1) ought to be unnecessary.  But remote_wait in GDB
663b725ae77Skettenis 	     will claim this event belongs to inferior_ptid if we do not
664b725ae77Skettenis 	     specify a thread, and there's no way for gdbserver to know
665b725ae77Skettenis 	     what inferior_ptid is.  */
666b725ae77Skettenis 	  if (1 || old_thread_from_wait != thread_from_wait)
667e93f7393Sniklas 	    {
668b725ae77Skettenis 	      general_thread = thread_from_wait;
669e93f7393Sniklas 	      sprintf (buf, "thread:%x;", thread_from_wait);
670e93f7393Sniklas 	      buf += strlen (buf);
671e93f7393Sniklas 	      old_thread_from_wait = thread_from_wait;
672e93f7393Sniklas 	    }
673e93f7393Sniklas 	}
674e93f7393Sniklas     }
675e93f7393Sniklas   /* For W and X, we're done.  */
676e93f7393Sniklas   *buf++ = 0;
677e93f7393Sniklas }
678e93f7393Sniklas 
679e93f7393Sniklas void
decode_m_packet(char * from,CORE_ADDR * mem_addr_ptr,unsigned int * len_ptr)680b725ae77Skettenis decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
681e93f7393Sniklas {
682e93f7393Sniklas   int i = 0, j = 0;
683e93f7393Sniklas   char ch;
684e93f7393Sniklas   *mem_addr_ptr = *len_ptr = 0;
685e93f7393Sniklas 
686e93f7393Sniklas   while ((ch = from[i++]) != ',')
687e93f7393Sniklas     {
688e93f7393Sniklas       *mem_addr_ptr = *mem_addr_ptr << 4;
689e93f7393Sniklas       *mem_addr_ptr |= fromhex (ch) & 0x0f;
690e93f7393Sniklas     }
691e93f7393Sniklas 
692e93f7393Sniklas   for (j = 0; j < 4; j++)
693e93f7393Sniklas     {
694e93f7393Sniklas       if ((ch = from[i++]) == 0)
695e93f7393Sniklas 	break;
696e93f7393Sniklas       *len_ptr = *len_ptr << 4;
697e93f7393Sniklas       *len_ptr |= fromhex (ch) & 0x0f;
698e93f7393Sniklas     }
699e93f7393Sniklas }
700e93f7393Sniklas 
701e93f7393Sniklas void
decode_M_packet(char * from,CORE_ADDR * mem_addr_ptr,unsigned int * len_ptr,char * to)702b725ae77Skettenis decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
703b725ae77Skettenis 		 char *to)
704e93f7393Sniklas {
705b725ae77Skettenis   int i = 0;
706e93f7393Sniklas   char ch;
707e93f7393Sniklas   *mem_addr_ptr = *len_ptr = 0;
708e93f7393Sniklas 
709e93f7393Sniklas   while ((ch = from[i++]) != ',')
710e93f7393Sniklas     {
711e93f7393Sniklas       *mem_addr_ptr = *mem_addr_ptr << 4;
712e93f7393Sniklas       *mem_addr_ptr |= fromhex (ch) & 0x0f;
713e93f7393Sniklas     }
714e93f7393Sniklas 
715e93f7393Sniklas   while ((ch = from[i++]) != ':')
716e93f7393Sniklas     {
717e93f7393Sniklas       *len_ptr = *len_ptr << 4;
718e93f7393Sniklas       *len_ptr |= fromhex (ch) & 0x0f;
719e93f7393Sniklas     }
720e93f7393Sniklas 
721e93f7393Sniklas   convert_ascii_to_int (&from[i++], to, *len_ptr);
722e93f7393Sniklas }
723b725ae77Skettenis 
724*63addd46Skettenis /* Ask GDB for the address of NAME, and return it in ADDRP if found.
725*63addd46Skettenis    Returns 1 if the symbol is found, 0 if it is not, -1 on error.  */
726*63addd46Skettenis 
727b725ae77Skettenis int
look_up_one_symbol(const char * name,CORE_ADDR * addrp)728b725ae77Skettenis look_up_one_symbol (const char *name, CORE_ADDR *addrp)
729b725ae77Skettenis {
730b725ae77Skettenis   char own_buf[266], *p, *q;
731b725ae77Skettenis   int len;
732*63addd46Skettenis   struct sym_cache *sym;
733*63addd46Skettenis 
734*63addd46Skettenis   /* Check the cache first.  */
735*63addd46Skettenis   for (sym = symbol_cache; sym; sym = sym->next)
736*63addd46Skettenis     if (strcmp (name, sym->name) == 0)
737*63addd46Skettenis       {
738*63addd46Skettenis 	*addrp = sym->addr;
739*63addd46Skettenis 	return 1;
740*63addd46Skettenis       }
741b725ae77Skettenis 
742b725ae77Skettenis   /* Send the request.  */
743b725ae77Skettenis   strcpy (own_buf, "qSymbol:");
744b725ae77Skettenis   hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
745b725ae77Skettenis   if (putpkt (own_buf) < 0)
746b725ae77Skettenis     return -1;
747b725ae77Skettenis 
748b725ae77Skettenis   /* FIXME:  Eventually add buffer overflow checking (to getpkt?)  */
749b725ae77Skettenis   len = getpkt (own_buf);
750b725ae77Skettenis   if (len < 0)
751b725ae77Skettenis     return -1;
752b725ae77Skettenis 
753b725ae77Skettenis   if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
754b725ae77Skettenis     {
755b725ae77Skettenis       /* Malformed response.  */
756b725ae77Skettenis       if (remote_debug)
757b725ae77Skettenis 	{
758b725ae77Skettenis 	  fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
759b725ae77Skettenis 	  fflush (stderr);
760b725ae77Skettenis 	}
761b725ae77Skettenis 
762b725ae77Skettenis       return -1;
763b725ae77Skettenis     }
764b725ae77Skettenis 
765b725ae77Skettenis   p = own_buf + strlen ("qSymbol:");
766b725ae77Skettenis   q = p;
767b725ae77Skettenis   while (*q && *q != ':')
768b725ae77Skettenis     q++;
769b725ae77Skettenis 
770b725ae77Skettenis   /* Make sure we found a value for the symbol.  */
771b725ae77Skettenis   if (p == q || *q == '\0')
772b725ae77Skettenis     return 0;
773b725ae77Skettenis 
774b725ae77Skettenis   decode_address (addrp, p, q - p);
775*63addd46Skettenis 
776*63addd46Skettenis   /* Save the symbol in our cache.  */
777*63addd46Skettenis   sym = malloc (sizeof (*sym));
778*63addd46Skettenis   sym->name = strdup (name);
779*63addd46Skettenis   sym->addr = *addrp;
780*63addd46Skettenis   sym->next = symbol_cache;
781*63addd46Skettenis   symbol_cache = sym;
782*63addd46Skettenis 
783b725ae77Skettenis   return 1;
784b725ae77Skettenis }
785