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